home *** CD-ROM | disk | FTP | other *** search
/ Your Choice 3 / Your Choice Software Collection 3.iso / prgmming / swag08 / graphics.swg < prev    next >
Text File  |  1994-09-22  |  219KB  |  2 lines

  1. SWAGOLX.EXE (c) 1993 GDSOFT  ALL RIGHTS RESERVED 00036                                                                           1      08-24-9412:55ALL                      DAVID ROZENBERG          3D Rotation Objects      SWAG9408    Ü▐j╜    61     ╓   π{ Here is a program to rotate any object in 3D. }ππ(********************************************************π * This program was written by David Rozenberg          *π *                                                      *π * The program show how to convert a 3D point into a 2D *π * plane like the computer screen. So it will give you  *π * the illusion of 3D shape.                            *π *                                                      *π * You can rotate it by the keyboard arrows, for nonstop*π * rotate press Shift+Arrow                             *π *                                                      *π * Please use the program as it is without changing it. *π *                                                      *π * Usage:                                               *π *   3D FileName.Ext                                    *π *                                                      *π * There are some files for example how to build them   *π * the header " ; 3D by David Rozenberg " must be at the*π * beging of the file.                                  *π *                                                      *π ********************************************************)ππProgram G3d;π{$E+,N+}πUsesπ Crt,Graph;ππTypeπ  Coordinate = Array[1..7] of Real;π  Point = Recordπ            X,Y,Z : Real;π          End;π  LineRec = ^LineType;π  LineType = Recordπ               FPoint,TPoint : Point;π               Color : Byte;π               Next  : LineRec;π             End;πππVarπ  FirstLine : LineRec;π  Last      : LineRec;ππProcedure Init;πVarπ  GraphDriver,GraphMode,GraphError : Integer;ππBeginπ  GraphDriver:=Detect;π  initGraph(GraphDriver,GraphMode,'\turbo\tp');  { your BGI driver address }π  GraphError:=GraphResult;π  if GraphError<>GrOk then beginπ    clrscr;π    writeln('Error while turning to graphics mode.');π    writeln;π    halt(2);π  end;πEnd;πππFunction DegTRad(Deg : Real) : real;πBeginπ  DegTRad:=Deg/180*Pi;πEnd;ππProcedure ConvertPoint (P : Point;Var X,Y : Integer);πVarπ  Dx,Dy : Real;ππBeginπ  X:=GetMaxX Div 2;π  Y:=GetMaxY Div 2;π  Dx:=(P.Y)*cos(pi/6);π  Dy:=-(P.Y)*Sin(Pi/6);π  Dx:=Dx+(P.X)*Cos(pi/3);π  Dy:=Dy+(P.X)*Sin(Pi/3);π  Dy:=Dy-P.Z;π  X:=X+Round(Dx);π  Y:=Y+Round(Dy);πEnd;ππProcedure DrawLine(Lrec : LineRec);πVarπ  Fx,Fy,Tx,Ty : Integer;ππBeginπ  SetColor(Lrec^.Color);π  ConvertPoint(LRec^.FPoint,Fx,Fy);π  ConvertPoint(LRec^.TPoint,Tx,Ty);π  Line(Fx,Fy,Tx,Ty);πEnd;ππProcedure ShowLines;πVarπ  Lp : LineRec;ππBeginπ  ClearDevice;π  Lp:=FirstLine;π  While Lp<>Nil do Beginπ    DrawLine(Lp);π    Lp:=Lp^.Next;π  end;πEnd;ππProcedure Error(Err : Byte;S : String);πBeginπ  Clrscr;π  Writeln;π  Case Err ofπ    1 : Writeln('File : ',S,' not found!');π    2 : Writeln(S,' isn''t a 3d file!');π    3 : Writeln('Error in line :',S);π    4 : Writeln('No file was indicated');π  End;π  Writeln;π  Halt(Err);πEnd;ππProcedure AddLine(Coord : Coordinate);πVarπ  Lp : LineRec;ππBeginπ  New(Lp);π  Lp^.Color:=Round(Coord[7]);π  Lp^.FPoint.X:=Coord[1];π  Lp^.FPoint.Y:=Coord[2];π  Lp^.FPoint.Z:=Coord[3];π  Lp^.TPoint.X:=Coord[4];π  Lp^.TPoint.Y:=Coord[5];π  Lp^.TPoint.Z:=Coord[6];π  Lp^.Next:=Nil;π  If Last=Nil then FirstLine:=Lp else Last^.Next:=Lp;π  Last:=Lp;πend;ππProcedure LoadFile(Name : String);πVarπ  F : Text;π  Coord : Coordinate;π  S,S1 : String;π  I : Byte;π  LineNum : Word;π  Comma : Integer;ππBeginπ  FirstLine:=Nil;π  Last:=Nil;π  Assign(F,Name);π  {$I-}π  Reset(f);π  {$I+}π  If IoResult<>0 then Error(1,Name);π  Readln(F,S);π  If S<>'; 3D by David Rozenberg' then Error(2,Name);π  LineNum:=1;π  While Not Eof(F) do Beginπ    Inc(LineNum);π    Readln(F,S);π    while Pos(' ',S)<>0 do Delete(S,Pos(' ',S),1);π    If (S<>'') and (S[1]<>';') then beginπ      For I:=1 to 6 do Beginπ        Comma:=Pos(',',S);π        If Comma=0 then Beginπ          Close(F);π          Str(LineNum:4,S);π          Error(3,S);π        End;π        S1:=Copy(S,1,Comma-1);π        Delete(S,1,Comma);π        Val(S1,Coord[i],Comma);π        If Comma<>0 then Beginπ          Close(F);π          Str(LineNum:4,S);π          Error(3,S);π        End;π      End;π      Val(S,Coord[7],Comma);π      If Comma<>0 then Beginπ        Close(F);π        Str(LineNum:4,S);π        Error(3,S);π      End;π      AddLine(Coord);π    End;π  End;π  Close(F);πEnd;ππProcedure RotateZ(Deg : Real);πVarπ  Lp : LineRec;π  Rad : Real;π  Tx,Ty : Real;ππBeginπ  Rad:=DegTRad(Deg);π  Lp:=FirstLine;π  While Lp<>Nil do Beginπ    With Lp^.Fpoint Do Beginπ      TX:=(X*Cos(Rad)-Y*Sin(Rad));π      TY:=(X*Sin(Rad)+Y*Cos(Rad));π      X:=Tx;π      Y:=Ty;π    End;π    With Lp^.Tpoint Do Beginπ      TX:=(X*Cos(Rad)-Y*Sin(Rad));π      TY:=(X*Sin(Rad)+Y*Cos(Rad));π      X:=Tx;π      Y:=Ty;π    End;π    Lp:=Lp^.Next;π  end;πEnd;ππProcedure RotateY(Deg : Real);πVarπ  Lp : LineRec;π  Rad : Real;π  Tx,Tz : Real;ππBeginπ  Rad:=DegTRad(Deg);π  Lp:=FirstLine;π  While Lp<>Nil do Beginπ    With Lp^.Fpoint Do Beginπ      TX:=(X*Cos(Rad)-Z*Sin(Rad));π      TZ:=(X*Sin(Rad)+Z*Cos(Rad));π      X:=Tx;π      Z:=Tz;π    End;π    With Lp^.Tpoint Do Beginπ      TX:=(X*Cos(Rad)-Z*Sin(Rad));π      TZ:=(X*Sin(Rad)+Z*Cos(Rad));π      X:=Tx;π      Z:=Tz;π    End;π    Lp:=Lp^.Next;π  end;πEnd;ππProcedure Rotate;πVarπ  Ch : Char;ππBeginπ  Repeatπ    Repeatπ      Ch:=Readkey;π      If ch=#0 then Ch:=Readkey;π    Until Ch in [#27,#72,#75,#77,#80,#50,#52,#54,#56];π    Case ch ofπ      #54 :Beginπ              While Not keypressed do beginπ                RotateZ(10);π                ShowLines;π                Delay(100);π              End;π              Ch:=Readkey;π              If Ch=#0 then Ch:=ReadKey;π            End;π      #52:Beginπ              While Not keypressed do beginπ                RotateZ(-10);π                ShowLines;π                Delay(100);π              End;π              Ch:=Readkey;π              If Ch=#0 then Ch:=ReadKey;π            End;π      #56:Beginπ              While Not keypressed do beginπ                RotateY(10);π                ShowLines;π                Delay(100);π              End;π              Ch:=Readkey;π              If Ch=#0 then Ch:=ReadKey;π            End;π      #50:Beginπ              While Not keypressed do beginπ                RotateY(-10);π                ShowLines;π                Delay(100);π              End;π              Ch:=Readkey;π              If Ch=#0 then Ch:=ReadKey;π            End;π      #72 : Beginπ              RotateY(10);π              ShowLines;π            End;π      #75 : Beginπ              RotateZ(-10);π              ShowLines;π            End;π      #77 : Beginπ              RotateZ(10);π              ShowLines;π            End;π      #80 : Beginπ              RotateY(-10);π              ShowLines;π            End;π    End;π  Until Ch=#27;πEnd;ππBeginπ  If ParamCount<1 then Error(4,'');π  LoadFile(ParamStr(1));π  Init;π  ShowLines;π  Rotate;π  CloseGraph;π  ClrScr;π  Writeln;π  Writeln('Thanks for using 3D');π  Writeln;πEnd.ππThere is sample of some files that can be rotated:πcut out and save in specified file nameπCube.3D:ππ; 3D by David Rozenbergπ; Base of cubeπ-70,70,-70,70,70,-70,15π70,70,-70,70,-70,-70,15π70,-70,-70,-70,-70,-70,15π-70,-70,-70,-70,70,-70,15π; Top of cubeπ-70,70,70,70,70,70,15π70,70,70,70,-70,70,15π70,-70,70,-70,-70,70,15π-70,-70,70,-70,70,70,15π; Side of cubeπ-70,70,-70,-70,70,70,13π70,70,-70,70,70,70,13π70,-70,-70,70,-70,70,13π-70,-70,-70,-70,-70,70,13ππDavid.3D:ππ; 3D by David Rozenbergπ0,-120,45,0,-30,45,15π0,-60,45,0,-60,-45,15π; π0,-15,45,0,15,45,12π0,15,45,0,15,-45,12π;π0,30,45,0,120,45,11π0,90,45,0,90,-45,11π;π50,-45,-75,50,45,-75,10π50,45,-75,50,45,-165,10ππ                                                     2      08-24-9413:26ALL                      JOHN HOWARD              Bounce v1.1              SWAG9408    ░Dp    61     ╓   (*π  From: Christian Ramsvikπ  Subj: bounce    v1.0πOrigin: Hatlane Point #9 (2:211/10.9)ππHI!  Got a bouncing procedure a while ago.  It bounces a ball, and you canπincrease speed in X- and Y-axis by pressing the arrow keys.  I'm sure you canπextract what you need from this one:πππ  From: John Howard  jhπ  Subj: bounce    v1.1πOrigin: Synergy (1:280/66)πUpgraded to vary the ball size with / and *.  Compass directions use keypad inπnumlock mode or UIOJKNM, keys.  The speed can be changed in each direction.πThe gravity effect can vary with + and - keys.  Status report dialog box whenπeither space or 0 key pressed.  Press 0 again will stop all motion.  Pressπkeypad_5 will halt display and requires pressing ESCape key to continue.  Aπperiod will reset the ball to default size.π*)ππprogram Bounce;πuses Crt, Graph;π{-$DEFINE solid}π{-$DEFINE bubble}π{ jhπconstπ     MinBalls = 1;π     MaxBalls = 2;π}πtypeπ    TImage = recordπ               XPos,                   {x}       {horizontal position}π               YPos    : Integer;      {y}       {vertical position}π               XSpeed,                 {dx}      {actually a velocity}π               YSpeed  : Integer;      {dy}      {actually a velocity}π               XAccel,                 {ddx}     {jh unused acceleration}π               YAccel  : Integer;      {ddy}     {jh unused acceleration}ππ               Radius  : Byte;         {Ball}π             end;ππvarπ   Ch     : Char;π   Gd, Gm : Integer;π   Image  : {array [MinBalls..MaxBalls] of} TImage;   {jh}π   FullSpeed,                                         {jh}π   HalfSpeed : Integer;           { = FullSpeed div 2}π   {BallNumber : byte;}                               {jh}ππ{ ******************* DRAW IMAGE ********************* }πprocedure DrawImage;πbeginπ   SetColor( White );π{$IFDEF solid}π   SetFillStyle( SolidFill, White );π{$ELSE}π   SetFillStyle( HatchFill, White );π{$ENDIF}ππ   with Image doπ   beginπ{$IFDEF bubble}π      Circle( XPos, YPos, Radius );              {jh Soap bubble}π{$ELSE}π      PieSlice( XPos, YPos, 0, 360, Radius );    {jh Pattern ball}π{$ENDIF}π   end;πend;ππ{ ******************* REMOVE IMAGE ******************** }πprocedure RemoveImage;πbeginπ   SetColor( Black );π{$IFDEF solid}π   SetFillStyle( SolidFill, Black );π{$ELSE}π   SetFillStyle( HatchFill, Black );π{$ENDIF}ππ   with Image doπ   beginπ{$IFDEF bubble}π      Circle( XPos, YPos, Radius );              {jh Soap bubble}π{$ELSE}π      PieSlice( XPos, YPos, 0, 360, Radius );    {jh Pattern ball}π{$ENDIF}π   end;πend;ππ{ ******************* UPDATE SPEED ******************** }πprocedure UpdateSpeed;ππ         function IntToStr(I: Longint): String;π         { convert any integer to a string }π         var  S: string[11];π         beginπ           Str(I,S);π           IntToStr := S;π         end;πbeginπ   while KeyPressed doπ   beginπ     Ch := ReadKey;π     Ch := Upcase(Ch);π     case Ch of  { Change speed with keypad numbers }π{jh Note: Keypad_5 causes a halt until escape key pressed}ππ         '.': Image.Radius := 16;                   {Default}π         '/': Image.Radius := Image.Radius shr 1;   {Reduce}π         '*': Image.Radius := Image.Radius shl 1;   {Enlarge}π         '+': beginπ                Inc(FullSpeed);π                HalfSpeed := FullSpeed div 2;π              end;π         '-': beginπ                Dec(FullSpeed);π                HalfSpeed := FullSpeed div 2;π              end;π         '8','I': Dec( Image.YSpeed, FullSpeed );   {N upwards}π         '2','M': Inc( Image.YSpeed, FullSpeed );   {S downwards}π         '4','J': Dec( Image.XSpeed, FullSpeed );   {W leftwards}π         '6','K': Inc( Image.XSpeed, FullSpeed );   {E rightwards}π         '0',' ': begin                             {Report statistics}π                    SetColor( White );π                    SetFillStyle( SolidFill, White );π                    Rectangle(8,8,8+160,8+56);                      {box}π                    SetViewPort(8,8,8+160,8+56, ClipOff);           {dialog}π                    OutTextXY(2,2, '<ENTER> resumes');π                    OutTextXY(2,2+8,  'x = ' + IntToStr(Image.XPos));π                    OutTextXY(2,2+16, 'y = ' + IntToStr(Image.YPos));π                    OutTextXY(2,2+24, 'dx = '+ IntToStr(Image.XSpeed));π                    OutTextXY(2,2+32, 'dy = '+ IntToStr(Image.YSpeed));π                    OutTextXY(2,2+40, 'Full Speed = '+ IntToStr(FullSpeed));ππ                    Ch := ReadKey;                 {repeat until keypressed}π                    ClearViewPort;π                    SetViewPort(0,0,GetMaxX,GetMaxY, ClipOn);       {window}π                    Rectangle(0,0,GetMaxX,GetMaxY);                 {border}π                    if (Ch = '0') then              {Stop motion}π                     beginπ                       Image.XSpeed := 0;π                       Image.YSpeed := 0;π                     end;π                  end;π         '7','U': begin                      {NW}π                    Dec(Image.XSpeed, HalfSpeed);π                    Dec(Image.YSpeed, HalfSpeed);π                  end;π         '9','O': begin                      {NE}π                    Inc(Image.XSpeed, HalfSpeed);π                    Dec(Image.YSpeed, HalfSpeed);π                  end;π         '1','N': begin                      {SW}π                    Dec(Image.XSpeed, HalfSpeed);π                    Inc(Image.YSpeed, HalfSpeed);π                  end;π         '3',',': begin                      {SE}π                    Inc(Image.XSpeed, HalfSpeed);π                    Inc(Image.YSpeed, HalfSpeed);π                  end;ππ     end;  {case}π   end;π   Inc( Image.YSpeed, HalfSpeed );  { Gravitation }  {jh Just so it can vary}πend;ππ{ ****************** UPDATE POSITIONS ****************** }πprocedure UpdatePositions;πbeginπ   Inc( Image.XPos, Image.XSpeed );π   Inc( Image.YPos, Image.YSpeed );πend;ππ{ ****************** CHECK COLLISION ******************* }πprocedure CheckCollision;πbeginπ   with Image doπ   beginπ      if ( XPos - Radius ) <= 0 then  { Hit left wall }π         beginπ         XPos   := Radius +1;π         XSpeed := -Trunc( XSpeed *0.9 );π         end;ππ      if ( XPos + Radius ) >= GetMaxX then { Hit right wall }π         beginπ         XPos   := GetMaxX -Radius -1;π         XSpeed := -Trunc( XSpeed *0.9 );π         end;ππ      if ( YPos -Radius ) <= 0 then  { Hit roof }π         beginπ         YPos   := Radius +1;π         YSpeed := -Trunc( YSpeed *0.9 );π         end;ππ      if ( YPos +Radius ) >= GetMaxY then { Hit floor }π         beginπ         YPos   := GetMaxY -Radius -1;π         YSpeed := -Trunc( YSpeed *0.9 );π         end;π   end;πend;ππ{ ********************* PROGRAM ************************ }ππBEGINπ   FullSpeed := 10;π   HalfSpeed := FullSpeed div 2;π   with Image doπ   beginπ      XPos   := 30;π      YPos   := 30;π      XSpeed := FullSpeed;π      YSpeed :=  0;π      XAccel :=  0;             {jh unused}π      YAccel := 10;             {jh unused}ππ      Radius := 16;             {arbitrary}π   end;ππ   Gd := Detect;π   InitGraph( Gd, Gm, '');            {BGI drivers in Current Work Dir (CWD)}π   Gd := GraphResult;π   if (Gd <> grOK) thenπ     beginπ       Gd := Detect;π       InitGraph( Gd, Gm, '\TURBO\TP\');     {BGI drivers in default directory}π     end;π   Rectangle( 0, 0, GetMaxX, GetMaxY );                 {border}π   SetViewPort( 0, 0, GetMaxX, GetMaxY, ClipOn );       {window}ππ   repeatπ      DrawImage;π      Delay( 30 );    {milliseconds Frame delay}π      RemoveImage;ππ      UpdateSpeed;π      UpdatePositions;π      CheckCollision;π   until Ch = Chr( 27 );ππ   CloseGraph;πEND.π                         3      08-24-9413:27ALL                      LUIS MEZQUITA RAYA       Cannon Ball Animation    SWAG9408    ^¬fτ    20     ╓   {π JG> This coding works fine, I would like to make the ball travelπ JG> smoother.  When it travels in the air, its kinda "Chunky"ππ JG> How could you make it so that the computer calculates the nextπ JG> point and make it travel the ball to that point one pixel at aπ JG> time?  Cause with this structure, it kinda "Jumps there"ππ        Try next code and tell me ...π}ππProgram FallingBall;ππ{ Written by Luis Mezquita Raya }ππ{$x+}ππuses  Crt,π      Graph;ππProcedure Init;πvar cg,mg:integer;πbeginπ cg:=Detect;π InitGraph(cg,mg,'\turbo\tp');πend;ππProcedure Wait(msk:byte); assembler;πasmπ        mov dx,3dahπ@Loop1: in al,dxπ        test al,mskπ        jz @Loop1π@Loop2: in al,dxπ        test al,mskπ        jnz @Loop2πend;ππProcedure Calc;πvar angle,power,gravity,a1,a2,a3,y0,n:real;π    size:word;π    ball,mask,bkg:pointer;π    x,y,ox,oy,pause:integer;πbeginππ ClearViewPort;ππ size:=ImageSize(0,0,20,20);π GetMem(ball,size);π GetMem(mask,size);π GetMem(bkg,size);ππ SetFillStyle(SolidFill,Yellow);        { Draw a ball }π Circle(10,10,8);π FloodFill(10,10,White);π GetImage(0,0,20,20,ball^);             { Get the ball }ππ SetFillStyle(SolidFill,White);         { Draw ball's mask }π Bar(0,0,20,20);π SetFillStyle(SolidFill,Black);π SetColor(Black);π Circle(10,10,10);π FloodFill(10,10,Black);π GetImage(0,0,20,20,mask^);             { Get the mask }ππ ClearViewPort;                         { Draw a background }π SetFillStyle(CloseDotFill,LightBlue);π Bar(0,0,GetMaxX,GetMaxY);ππ angle:=35;                             { Init vars }π power:=10;π gravity:=0.1;π y0:=200;π ox:=-1;π n:=0;ππ while n<80 do                          { Main loop }π  beginπ   a1:=cos(angle*pi/180)*power*n;π   a2:=y0-sin(angle*pi/180)*power*n;π   a3:=gravity*n*n;π   x:=Round(a1);π   y:=Round(a2+a3);π   Wait(8);                             { Wait retrace }π   for pause:=0 to 399 do Wait(1);      { Wait scan line }π   if ox<>-1                            { Restore old background }π   then PutImage(ox,oy,bkg^,CopyPut);π   GetImage(x,y,x+20,y+20,bkg^);        { Save background }π   PutImage(x,y,mask^,AndPut);          { Put mask }π   PutImage(x,y,ball^,OrPut);           { Put ball }π   ox:=x;π   oy:=y;π   n:=n+0.2;π  end;ππ FreeMem(ball,size);π FreeMem(mask,size);πend;πππbeginπ Init;π Calc;π ReadKey;π CloseGraph;πend.π                                                                                                                       4      08-24-9413:28ALL                      JOHN HOWARD              Coordinate Systems       SWAG9408    Å∞┼W    70     ╓   {π -=> Quoting Sean Graham to All on 22 Jun 94 <=-π SG> some  (efficient, I would hope) code in pascal that will allow me toπ SG> move in a 2D or  3D 'universe' (or more correctly, grid-system). Let meππ SG> Let's start out easy.  For example, how would I write code to draw aπ SG> line on  a 50x80 (yes, ascii chars) screen from pos A(10,5) to posπ SG> B(47,56)?π SG> Now imagine that my screen has magically grown a third dimention.  Soπ SG> I now  want to draw a line from pos A(47,34,7) to pos B(21,11,33).  Howπ SG> would I write  code to do that?ππ SG> Now picture this, I no longer have a screen, but a grid that worksπ SG> along the same principles as the screen did, except the points rangeπ SG> from -20 to +20 on (x,y,z).  (That gives me a total of 68,921 (41^3)π SG> possible co-ordinates.)π SG> Pretend that Is a universe in space.  I'm in a tiny escape pod andπ SG> must get from co-ordinate (-10,+05,+12) to co-ordinate (+07,+02,-11)ππIf you want to create an actual space, try :π}ππUNIT space;π{ Author: John Howard }π{πDefine a two-dimensional space representation which is used for Cartesian andπPolar coordinate systems.  A three-dimensional space is for Spherical andπAzimuth-Elevation coordinate systems.π}π{ A vector is a one-dimensional array of real numbers.  A matrix has twoπ  dimensions m by n with m rows and n columns.  Notice the row number alwaysπ  comes first in the dimensions and the indices.  Example square matrix A33 =π             [ a11  a12  a13 ]    or generally  A[i, j]; i=rows, j=columns.π             [ a21  a22  a23 ]π             [ a31  a32  a33 ]π  A matrix can be operated upon with appropriate column or row vectors.π}πINTERFACEπ{.$DEFINE D2}                            {remove period to use 2D}π{$IFNDEF D2}πconst N = 3;                             { Cardinality for Three_Vector}π      M = 3;                             { Square matrix for invert routine}π{$ELSE}πconst N = 2;                             { Cardinality for Two_Vector}π      M = 2;                             { Square matrix for invert routine}π{$ENDIF}π   Size = M;πtypeπ   Vector = array [1..N] of real;        { 3D vector is the most common! }π   Matrix = array [1..M, 1..N] of real;  { 3x3 matrix is the most common! }ππ{Store all the components into a vector}π{$IFNDEF D2}π   procedure Set_Value( var a: Vector; x_value, y_value, z_value: real);π{$ELSE}π   procedure Set_Value( var a: Vector; x_value, y_value: real);π{$ENDIF}ππ{Retrieve the value of s from the ith element of a vector}π   function Element( var a: Vector; i: integer): real;ππ{Retrieve the first element from a vector}π   function  X_Component( var a: Vector): real;ππ{Retrieve the second element from a vector}π   function  Y_Component( var a: Vector): real;ππ{Retrieve the third element from a vector}π{$IFNDEF D2}π   function  Z_Component( var a: Vector): real;π{$ENDIF}ππIMPLEMENTATIONππprocedure Set_Value;          { Note: parameter list intentionally left off}πbeginπ      a[1] := x_value;π      a[2] := y_value;π{$IFNDEF D2}π      a[3] := z_value;π{$ENDIF}πend;ππfunction Element( var a: Vector; i: integer): real;πbeginπ      Element := a[i];πend;ππfunction  X_Component( var a: Vector): real;πbeginπ      X_Component := a[1];πend;ππfunction  Y_Component( var a: Vector): real;πbeginπ      Y_Component := a[2];πend;ππ{$IFNDEF D2}πfunction  Z_Component( var a: Vector): real;πbeginπ      Z_Component := a[3];πend;π{$ENDIF}πBEGINπEND.ππ(**********πIf you do not want to create an actual 3d space, just convert coordinates :ππYou could use a two dimensional X_Component and Y_Component calculation to getπyou to an approximate region based upon Z_Component.  Example:ππFrom point A(x1,y1) to B(x2,y2) you travel a distance = sqrt(sqr(x2-x1) +π  sqr(y2-y1)) at a slope of (y2-y1)/(x2-x1).  That slope is called the Tangentπof the angle of inclination of the line AB.ππNow that you know where you are heading and how far away it is you can divideπthe total distance into sections say of unit length.  That means a distance ofπ10 would have ten units.  Every time your spaceship moves one unit in the knownπdirection you can reverse the calculation to find out where you are at.  Whenπyou reach the final distance, you'd take approximations using the thirdπcomponent.  This idea is simple but not very accurate in the interum space.ππYou can use the same idea but implement it with a proper coordinate conversion.π**********)ππUNIT coord;π{ Author: John Howard }π{ Original source: Jack Crenshaw, 1992 Embedded Systems Programming }π{ Space Conversion -- Angles are capitalized }π{ All axes are perpendicular to each other }πINTERFACEπconstπ      Zero = 0.0;π      One  = 1.0;π      TwoPi               = Two * SYSTEM.Pi;π      Pi_Over_Two         = SYSTEM.Pi/Two;ππ{ 1 binary angular measure = 1 pirad = Pi radians = 180 degrees }π      Degrees_Per_Radian  = 180.0/SYSTEM.Pi;π      Radians_Per_Degree  = SYSTEM.Pi/180.0;ππ{ X-axis points east, y-axis north, and angle Theta is the heading measuredπ  north of due east.  If Theta is zero that corresponds to a line runningπ  along the x-axis a radial distance of r.π}πProcedure To_Polar ( x, y: real; Var r, Theta: real);πProcedure From_Polar ( r, Theta: real; Var x, y: real);ππ{ X-axis points toward you, y-axis right, z-axis upward, angle Phi measuresπ  directions in the horizontal (x-y plane) from the x-axis, and angle Thetaπ  measures the direction in the vertical from the z-axis downward.  If Thetaπ  is zero that corresponds to a line pointed up the z-axis.π}πProcedure To_Spherical ( x, y, z: real; Var r, Phi, Theta: real);πProcedure From_Spherical ( r, Phi, Theta: real; Var x, y, z: real);ππ{ X-axis points east, y-axis north, z-axis upward, angle Phi corresponds to anπ  azimuth measured clockwise from due north, and angle Theta is the elevationπ  measured upwards from the horizon (x-y plane).π}πProcedure To_Azimuth_Elevation ( x, y, z: real; Var r, Phi, Theta: real);πProcedure From_Azimuth_Elevation ( r, Phi, Theta: real; Var x, y, z: real);ππFunction Sign ( x, y: real): real;πFunction Degrees ( A: real): real;πFunction Radians ( A: real): real;ππFunction Atan ( x: real): real;           {ArcTangent}πFunction Atan2 ( s, c: real): real;ππIMPLEMENTATIONππ{ Convert from Cartesian to polar coordinates }πProcedure To_Polar ( x, y: real; Var r, Theta: real);πBeginπ  r := Sqrt(Sqr(x) + Sqr(y));π  Theta := Atan2(y, x);πEnd;ππ{ Convert from polar to Cartesian coordinates }πProcedure From_Polar ( r, Theta: real; Var x, y: real);πBeginπ  x := r * Cos(Theta);π  y := r * Sin(Theta);πEnd;ππ{ Convert from Cartesian to spherical polar coordinates }πProcedure To_Spherical ( x, y, z: real; Var r, Phi, Theta: real);πvar  temp: real;πBeginπ  To_Polar(x, y, temp, Phi);π  To_Polar(z, temp, r, Theta);πEnd;ππ{ Convert from spherical polar to Cartesian coordinates }πProcedure From_Spherical ( r, Phi, Theta: real; Var x, y, z: real);πvar  temp: real;πBeginπ  From_Polar(r, Theta, z, temp);π  From_Polar(temp, Phi, x, y);πEnd;ππ{ Convert from Cartesian to Az-El coordinates }πProcedure To_Azimuth_Elevation ( x, y, z: real; Var r, Phi, Theta: real);πvar  temp: real;πBeginπ  To_Polar(y, x, temp, Phi);π  To_Polar(temp, z, r, Theta);πEnd;ππ{ Convert from Az-El to Cartesian coordinates }πProcedure From_Azimuth_Elevation ( r, Phi, Theta: real; Var x, y, z: real);πvar  temp: real;πBeginπ  From_Polar(r, Theta, temp, z);π  From_Polar(temp, Phi, y, x);πEnd;ππ{ Returns Absolute value of x with Sign of y }πFunction Sign ( x, y: real): real;πBeginπ  if y >= Zero thenπ     Sign := Abs(x)π  elseπ     Sign := -Abs(x);πEnd;ππ{ Convert angle from radians to degrees }πFunction Degrees ( A: real): real;πBeginπ  Degrees := Degrees_Per_Radian * A;πEnd;ππ{ Convert angle from degrees to radians }πFunction Radians ( A: real): real;πBeginπ  Radians := Radians_Per_Degree * A;πEnd;ππ{ Inverse Trigonometric Tangent Function }πFunction Atan ( x: real): real;π{  Arctangent algorithm uses fifth-order rational fraction with optimizedπ   coefficientsπ}π   function _Atan ( x: real): real;π   constπ     a = 0.999999447;π     b = 0.259455937;π     c = 0.592716128;ππ   var  y: real;π   beginπ      y := x*x;π      _Atan := a*x*( One + b*y) / ( One + c*y);π   end;ππvar  a, y: real;πBeginπ  y := Abs(x);π  if y <= One thenπ    a := _Atan(y)π  elseπ    a := Pi_Over_Two - _Atan( One / y);π  if x <= Zero thenπ    a := -a;π  Atan := a;πEnd;ππ{ Four-Quadrant Inverse Trigonometric Tangent Function }πFunction Atan2 ( s, c: real): real;πvar  s1, c1, Theta: real;πBeginπ  s1 := Abs(s);π  c1 := Abs(c);π  if c1 + s1 = Zero thenπ    Theta := Zeroπ  else if s1 <= c1 thenπ         Theta := ArcTan(s1 / c1)π       elseπ         Theta := Pi_Over_Two - ArcTan(c1 / s1);π  if c < Zero thenπ    Theta := Pi - Theta;π  Atan2 := Sign(Theta, s);πEnd;πBEGINπEND.π(*****END*****)π                               5      08-24-9413:32ALL                      IAIN WHYTE               DOT Matrix LED Effect    SWAG9408    ╞≥I     218    ╓   unit dotmat; {written by Iain Whyte. (c) 1994 }ππ{ This unit generates a 'dot matrix' LED effect that is very effective. Ifπyou would like to use this code, all that I ask is that you mention itπin the credits somewhere, and let me know what you used it for. If you haveπany suggestions, or you want to talk to me or ask questions, I can beπcontacted at whytei@topaz.ucq.edu.au or ba022@cq-pan.cqu.edu.auπvia the Internet, or by snail-post :ππ          Iain Whyteπ          141 Racecourse Roadπ          Mt Morgan Q4714π          Australia.ππor on the Rockhampton Computer Club BBS, via the programming, IBM/DOS, orπAMIGA conferences... RCC BBS: (079) 276200ππInstructions :ππSelf explanatary, really, there is a sample prog for using this unit at theπof this file..... }ππ{displays upto 10 characters at once, max string size (ATM) is 20 chars....}πππinterfaceππuses dos,crt,graph;ππππprocedure display_dotmat_screen(xpos,ypos:integer);πprocedure create_dotmat(inputstring:string);πprocedure straight_display;πprocedure left_right;πprocedure right_left;πprocedure top_bot;πprocedure bot_top;πprocedure italics;πprocedure random_fade_out;πprocedure random_fade_in;πprocedure fall_away;ππππimplementationπππtypeππletter_set=array[0..8,0..4] of integer;πdotmattype=array[0..8,0..119] of integer;ππconstπ     pixelsize = 2; {size of each LED element i.e. 2 therfore LED is 2x2 pixels}π     a : letter_set = ((0,1,1,1,0),  {each letter is set up as a 5x9 array}π                       (1,0,0,0,1),  {1 means LED is ON, 0 means LED OFF}π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,1,1,1,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1));π     b : letter_set = ((1,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,1,1,1,0));π     c : letter_set = ((0,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,1),π                       (0,1,1,1,0));π     d : letter_set = ((1,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,1,1,1,0));π     e : letter_set = ((1,1,1,1,1),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,1,1,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,1,1,1,1));π     f : letter_set = ((1,1,1,1,1),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,1,1,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0));π     g : letter_set = ((0,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,1,1,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,1,1,0));π     h : letter_set = ((1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,1,1,1,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1));π     i : letter_set = ((0,1,1,1,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,1,1,1,0));π     j : letter_set = ((0,0,1,1,1),π                       (0,0,0,1,0),π                       (0,0,0,1,0),π                       (0,0,0,1,0),π                       (0,0,0,1,0),π                       (1,0,0,1,0),π                       (1,0,0,1,0),π                       (1,0,0,1,0),π                       (0,1,1,0,0));π     k : letter_set = ((1,0,0,0,1),π                       (1,0,0,1,0),π                       (1,0,1,0,0),π                       (1,1,0,0,0),π                       (1,1,0,0,0),π                       (1,1,0,0,0),π                       (1,0,1,0,0),π                       (1,0,0,1,0),π                       (1,0,0,0,1));π     l : letter_set = ((1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,1,1,1,1));π     m : letter_set = ((1,0,0,0,1),π                       (1,1,0,1,1),π                       (1,1,1,1,1),π                       (1,0,1,0,1),π                       (1,0,1,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1));π     n : letter_set = ((1,0,0,0,1),π                       (1,1,0,0,1),π                       (1,1,0,0,1),π                       (1,0,1,0,1),π                       (1,0,1,0,1),π                       (1,0,1,0,1),π                       (1,0,0,1,1),π                       (1,0,0,1,1),π                       (1,0,0,0,1));π     o :  letter_set =((0,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,1,1,0));π     p :  letter_set =((1,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,1,1,1,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0));π     q :  letter_set =((0,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,1,0,1),π                       (1,0,0,1,1),π                       (0,1,1,1,1));π     r :  letter_set =((1,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,1,1,1,0),π                       (1,1,0,0,0),π                       (1,0,1,0,0),π                       (1,0,0,1,0),π                       (1,0,0,0,1));π     s :  letter_set =((0,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (0,1,1,1,0),π                       (0,0,0,0,1),π                       (0,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,1,1,0));π     t :  letter_set =((1,1,1,1,1),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0));π     u :  letter_set =((1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,1,1,0));π     v :  letter_set =((1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,0,1,0),π                       (0,1,0,1,0),π                       (0,0,1,0,0));π     w :  letter_set =((1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,1,0,1),π                       (1,0,1,0,1),π                       (0,1,1,1,0),π                       (0,1,0,1,0));π     x :  letter_set =((1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,0,1,0),π                       (0,0,1,0,0),π                       (0,1,0,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1));π     y :  letter_set =((1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,0,1,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0));π     z :  letter_set =((1,1,1,1,1),π                       (0,0,0,0,1),π                       (0,0,0,0,1),π                       (0,0,0,1,0),π                       (0,0,1,0,0),π                       (0,1,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,1,1,1,1));π     exc :  letter_set =((0,0,1,0,0),π                       (0,1,1,1,0),π                       (0,1,1,1,0),π                       (0,1,1,1,0),π                       (0,1,1,1,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,0,0,0),π                       (0,0,1,0,0));π     andm :  letter_set =((0,0,1,1,0),π                       (0,1,0,0,1),π                       (0,0,1,1,0),π                       (0,1,1,1,0),π                       (1,0,0,1,0),π                       (1,0,0,0,1),π                       (1,0,0,1,1),π                       (1,0,0,1,0),π                       (0,1,1,0,1));π     hat :  letter_set =((0,1,0,1,0),π                       (0,1,0,1,0),π                       (1,1,1,1,1),π                       (0,1,0,1,0),π                       (0,1,0,1,0),π                       (1,1,1,1,1),π                       (0,1,0,1,0),π                       (0,1,0,1,0),π                       (0,1,0,1,0));π     com :  letter_set =((0,0,0,0,0),π                       (0,0,0,0,0),π                       (0,0,0,0,0),π                       (0,0,0,0,0),π                       (0,0,0,0,0),π                       (0,0,1,1,0),π                       (0,0,1,1,0),π                       (0,0,1,0,0),π                       (0,1,1,0,0));π     ast : letter_set=((0,0,0,0,0),π                       (1,0,1,0,1),π                       (0,1,1,1,0),π                       (0,0,1,0,0),π                       (1,1,1,1,1),π                       (0,0,1,0,0),π                       (0,1,1,1,0),π                       (1,0,1,0,1),π                       (0,0,0,0,0));π     la : letter_set =((0,0,0,0,1),π                       (0,0,0,1,0),π                       (0,0,1,0,0),π                       (0,1,0,0,0),π                       (1,0,0,0,0),π                       (0,1,0,0,0),π                       (0,0,1,0,0),π                       (0,0,0,1,0),π                       (0,0,0,0,1));π     ra : letter_set =((1,0,0,0,0),π                       (0,1,0,0,0),π                       (0,0,1,0,0),π                       (0,0,0,1,0),π                       (0,0,0,0,1),π                       (0,0,0,1,0),π                       (0,0,1,0,0),π                       (0,1,0,0,0),π                       (1,0,0,0,0));π     one :letter_set =((0,0,1,0,0),π                       (0,1,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,1,1,1,0));π     two : letter_set=((0,1,1,1,0),π                       (1,0,0,0,1),π                       (0,0,0,0,1),π                       (0,0,0,1,0),π                       (0,0,1,0,0),π                       (0,1,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,1,1,1,1));π     thr: letter_set =((0,1,1,1,0),π                       (1,0,0,0,1),π                       (0,0,0,0,1),π                       (0,0,0,0,1),π                       (0,0,1,1,0),π                       (0,0,0,0,1),π                       (0,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,1,1,0));π     four:letter_set =((1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,1,0),π                       (1,0,0,1,0),π                       (1,0,0,1,0),π                       (1,0,0,1,0),π                       (1,1,1,1,1),π                       (0,0,0,1,0),π                       (0,0,0,1,0));π     five:letter_set =((1,1,1,1,1),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,1,1,1,0),π                       (1,0,0,0,1),π                       (0,0,0,0,1),π                       (0,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,1,1,0));π     six :letter_set =((0,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,0),π                       (1,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,1,1,0));π     sev :letter_set =((1,1,1,1,1),π                       (1,0,0,0,1),π                       (0,0,0,0,1),π                       (0,0,0,1,0),π                       (0,0,0,1,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,1,0,0,0),π                       (0,1,0,0,0));π    eight:letter_set =((0,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,1,1,0));π   nine : letter_set =((0,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,1,1,1),π                       (0,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,1,1,0));π   zer  : letter_set =((0,1,1,1,0),π                       (1,0,0,1,1),π                       (1,0,0,1,1),π                       (1,0,1,0,1),π                       (1,0,1,0,1),π                       (1,0,1,0,1),π                       (1,1,0,0,1),π                       (1,1,0,0,1),π                       (0,1,1,1,0));ππ   smil  :letter_set =((0,1,1,1,0),π                       (1,1,1,1,1),π                       (1,0,1,0,1),π                       (1,1,1,1,1),π                       (1,1,0,1,1),π                       (1,1,1,1,1),π                       (1,0,0,0,1),π                       (1,1,0,1,1),π                       (0,1,1,1,0));π   dol :  letter_set =((0,0,1,0,0),π                       (0,1,1,1,0),π                       (1,0,1,0,1),π                       (1,0,1,0,0),π                       (0,1,1,1,0),π                       (0,0,1,0,1),π                       (1,0,1,0,1),π                       (0,1,1,1,0),π                       (0,0,1,0,0));π   copyr: letter_set =((0,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,1,0,1),π                       (1,1,0,1,1),π                       (1,1,0,0,1),π                       (1,1,0,1,1),π                       (1,0,1,0,1),π                       (1,0,0,0,1),π                       (0,1,1,1,0));π   lb:    letter_set =((0,0,0,1,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,1,0,0,0),π                       (0,1,0,0,0),π                       (0,1,0,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,0,1,0));π   rb:    letter_set =((0,1,0,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,0,1,0),π                       (0,0,0,1,0),π                       (0,0,0,1,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,1,0,0,0));π   quest: letter_set =((0,1,1,1,0),π                       (1,0,0,0,1),π                       (0,0,0,0,1),π                       (0,0,0,1,0),π                       (0,0,0,1,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,0,0,0),π                       (0,0,1,0,0));πππvarπ  letters:array[' '..'z']of letter_set;π  outchars:array[0..19]of char;π  mainxpos,mainypos:integer;π  dotmatarray:dotmattype;π  dotmatarraymove,dotmatempty:dotmattype;π  counth,countv,lettercount:integer;π  count,count2,countmove,countloop:integer;ππprocedure setup_chars;ππbeginπ     letters['a']:=a;π     letters['b']:=b;π     letters['c']:=c;π     letters['d']:=d;π     letters['e']:=e;π     letters['f']:=f;π     letters['g']:=g;π     letters['h']:=h;π     letters['i']:=i;π     letters['j']:=j;π     letters['k']:=k;π     letters['l']:=l;π     letters['m']:=m;π     letters['n']:=n;π     letters['o']:=o;π     letters['p']:=p;π     letters['q']:=q;π     letters['r']:=r;π     letters['s']:=s;π     letters['t']:=t;π     letters['u']:=u;π     letters['v']:=v;π     letters['w']:=w;π     letters['x']:=x;π     letters['y']:=y;π     letters['z']:=z;π     letters['!']:=exc;π     letters['&']:=andm;π     letters['#']:=hat;π     letters[',']:=com;π     letters['*']:=ast;π     letters['<']:=la;π     letters['>']:=ra;π     letters['1']:=one;π     letters['2']:=two;π     letters['3']:=thr;π     letters['4']:=four;π     letters['5']:=five;π     letters['6']:=six;π     letters['7']:=sev;π     letters['8']:=eight;π     letters['9']:=nine;π     letters['0']:=zer;π     letters['^']:=smil;π     letters['$']:=dol;π     letters['@']:=copyr;π     letters['(']:=lb;π     letters[')']:=rb;π     letters['?']:=quest;πend;ππprocedure display_dotmat_screen(xpos,ypos:integer);ππvar countx,county:integer;ππbeginπ     mainxpos:=xpos;π     mainypos:=ypos;π     setfillstyle(1,8);π     for countx:=0 to 59 doπ     beginπ          for county:=-1 to 9 doπ          beginπ               bar((xpos+(countx*(pixelsize+1))),(ypos+(county*(pixelsize+1))),π                  ((xpos+(countx*(pixelsize+1)))+(pixelsize-1)),((ypos+(county*(pixelsize+1)))+(pixelsize-1)));ππ          end;π     end;πend;πππprocedure convertstring_to_chars(instr:string);ππvar count:integer;π    dummys:string[1];π    strcount:char;ππbeginπ     for count:=1 to 20 doπ     beginππ          dummys:=copy(instr,count,1);π          for strcount:=' ' to 'z' doπ          beginπ               if dummys = strcount then outchars[count-1]:=strcount;π          end;π     end;πend;πππprocedure create_dotmat(inputstring:string);ππbeginπ     for countv:=0 to 8 doπ     for counth:=0 to 119 doπ     dotmatempty[countv,counth]:=0;ππ     setup_chars;π     convertstring_to_chars(inputstring);ππ     for lettercount:=0 to 19 do  {make array of dots from letter data}π     beginππ     for countv:=0 to 8 doπ     beginππ          for counth :=(lettercount*6) to ((lettercount*6)+6) doπ          beginπ              if counth<120 thenπ              beginπ              dotmatarray[countv,counth]:=letters[outchars[lettercount],countv,(counth-lettercount*6)];π              if (counth-lettercount*6) > 4 then dotmatarray[countv,counth]:=0;π              end;π          end;π     end;π     end;ππππend;πππprocedure gen_display;ππbeginππ     for counth:=0 to 59 doπ     beginπ          for countv:=0 to 8 doπ          beginπ               if (counth < 2) or (counth > 57) then setfillstyle(1,2)π               else setfillstyle(1,10);π               if dotmatarraymove[countv,counth] = 1 thenπ               beginπ                  bar((mainxpos+(counth*(pixelsize+1))),(mainypos+(countv*(pixelsize+1))),π                  ((mainxpos+(counth*(pixelsize+1)))+(pixelsize-1)),((mainypos+(countv*(pixelsize+1)))+(pixelsize-1)));π               end;π               setfillstyle(1,8);π               if dotmatarraymove[countv,counth] = 0 thenπ               beginπ                   bar((mainxpos+(counth*(pixelsize+1))),(mainypos+(countv*(pixelsize+1))),π                  ((mainxpos+(counth*(pixelsize+1)))+(pixelsize-1)),((mainypos+(countv*(pixelsize+1)))+(pixelsize-1)));π               end;π          end;π     end;ππend;πππprocedure straight_display;ππbeginπ     dotmatarraymove:=dotmatarray;π     gen_display;πend;ππππprocedure left_right;πbeginππ     for count2:=0 to 119 doπ     beginπ          for count:=0 to 59 doπ          beginπ          countmove:=count+count2;π          if countmove>119 then countmove:=countmove-120;π          for countloop:=0 to 8 do dotmatarraymove[countloop,count]:=dotmatarray[countloop,countmove];ππ          end;π     gen_display;π     delay(5);π     end;πend;πππprocedure right_left;πbeginππ     for count2:=119 downto 0 doπ     beginππ          for count:=0 to 59 doπ          beginπ          countmove:=count+count2;π          if countmove>119 then countmove:=countmove-120;π          for countloop:= 0 to 8 do dotmatarraymove[countloop,count]:=dotmatarray[countloop,countmove];ππ          end;ππ     gen_display;π     delay(5);π     end;πend;πππprocedure top_bot;πbeginπ     dotmatarraymove:=dotmatempty;π     for count2:=-9 to 9 doπ     beginππ          for count:=0 to 8 doπ          beginπ            countmove:=count+count2;π          if countmove>8 then for countloop:=0 to 119 do dotmatarraymove[count,countloop]:=0π          else if countmove<0 then for countloop:=0 to 119 do dotmatarraymove[count,countloop]:=0π          else for countloop:=0 to 119 do dotmatarraymove[count,countloop]:=dotmatarray[countmove,countloop];ππ          end;ππ     gen_display;π     delay(50);π     end;πend;πππprocedure bot_top;πbeginπ     for count2:=9 downto -9 doπ     beginππ          for count:=0 to 8 doπ          beginπ            countmove:=count+count2;π           if countmove>8 then for countloop:=0 to 119 do dotmatarraymove[count,countloop]:=0π          else if countmove<0 then for countloop:=0 to 119 do dotmatarraymove[count,countloop]:=0π          else for countloop:=0 to 119 do dotmatarraymove[count,countloop]:=dotmatarray[countmove,countloop];ππππ          end;ππ     gen_display;π     delay(50);π     end;πππend;ππprocedure italics;πbeginπ     for count:=0 to 8 doπ     beginπ          for count2:=0 to 119 doπ          beginπ               if (count mod 2) = 0 thenπ               beginπ                    dotmatarraymove[count,count2]:=dotmatarray[count,count2+(count div 2)];π               end elseπ                    dotmatarraymove[count,count2]:=dotmatarray[count,count2+((count-1) div 2)];π          end;π     end;π     dotmatarray:=dotmatarraymove;πend;ππππprocedure random_fade_out;ππvarπv,h,rnd,countdots:integer;ππbeginπ     randomize;π     dotmatarraymove:=dotmatarray;π     countdots:=0;π     for v:=0 to 8 doπ     beginπ     for h:=0 to 119 doπ     beginπ         if dotmatarraymove[v,h]=1 thenππ         countdots:=countdots+1;π     end;π     end;π     repeatπ     for v:=0 to 8 doπ     beginπ     for h:=0 to 119 doπ     beginπ         if dotmatarraymove[v,h]=1 thenπ         beginπ              rnd:=random(5);π              if rnd = 1 thenπ              beginπ                   countdots:=countdots-1;π                   dotmatarraymove[v,h]:=0;π              end;π         end;π     end;π     end;ππ     gen_display;π     until countdots<=0;ππend;πππprocedure random_fade_in;πvarπv,h,rnd,countdots:integer;πbeginπ     randomize;π     dotmatarraymove:=dotmatempty;π     countdots:=0;π     for v:=0 to 8 doπ     beginπ     for h:=0 to 119 doπ     beginπ         if dotmatarray[v,h]=1 thenππ         countdots:=countdots+1;π     end;π     end;π     repeatπ     for v:=0 to 8 doπ     beginπ     for h:=0 to 119 doπ     beginπ         if (dotmatarray[v,h]=1)and (dotmatarraymove[v,h]=0) thenπ         beginπ              rnd:=random(5);π              if rnd = 1 thenπ              beginπ                   countdots:=countdots-1;π                   dotmatarraymove[v,h]:=1;π              end;π         end;π     end;π     end;ππ     gen_display;π     until countdots<=0;ππend;ππprocedure fall_away;πbeginπ     dotmatarraymove:=dotmatarray;π     for count:=8 downto 0 doπ     beginπ         count2:=count;π         repeatπ              for countloop:=0 to 119 doπ              beginπ                   if count2=count thenπ                   beginπ                   dotmatarraymove[count2,countloop]:=dotmatarray[count,countloop];π                   endπ                   elseπ                   beginπ                   dotmatarraymove[count2,countloop]:=dotmatarray[count,countloop];π                   dotmatarraymove[count2-1,countloop]:=0;π                   end;π              end;π            gen_display;π            delay(5);π         count2:=count2+1;π         until count2=10;ππ     end;πend;πππend.ππ{-------------------------------  DEMO  ----------------------------------}πprogram test_dotmat_unit;ππuses dos,crt,graph,dotmat;ππππvarπ   in1,in2:integer;πππbegin              {12345678901234567890}  {length guide}ππ     initgraph(in1,in2,'c:\bp\bgi');  {initialise 640x480x16c mode bgi}π     cleardevice;πππ     display_dotmat_screen(50,50);    {set_up, display blank LED matrix}ππ     create_dotmat('this is a demo !    '); {loads string into matrix array}ππ     straight_display;       {display on matrix}π     delay(1000);πππ     left_right;             {scroll from left to right}π     delay(1000);ππ     right_left;             {scroll from right to left}ππ     create_dotmat('fading in!           ');  {set up new msg}π     random_fade_in;                          {randomised fade}π     delay(1000);ππ     create_dotmat('fade out!!           ');π     straight_display;π     delay(1000);ππ     random_fade_out;πππ     create_dotmat('can scroll 4 ways!!! ');π     left_right;π     top_bot;       {scroll from top to bottom}π     right_left;π     bot_top;       {scroll from bottom to top}πππ     create_dotmat('italics for the font!'); {create new msg}π     italics;                                {generate italics}π     random_fade_in;π     left_right;π     delay(1000);π     random_fade_out;ππ     create_dotmat('and a special effect ');  {create new msg}π     left_right;π     delay(1000);π     create_dotmat('called fall away!    ');π     left_right;π     delay(1000);π     fall_away;                               {demo Special FX}ππ     create_dotmat('well, what dya think?');π     left_right;π     fall_away;ππ     create_dotmat('@ iain whyte 1994    ');π     random_fade_in;π     left_right;π     right_left;π     random_fade_out;π     top_bot;π     bot_top;ππππ     closegraph;                                    {kill graphics mode}ππend.π                                                                                                  6      08-24-9413:37ALL                      JENS LARSSON             Fast Line Drawing        SWAG9408    òy┴    9      ╓   {π SS> I'm looking for a qwick way to draw a line... All I need areπ SS> horizontal and vertical lines, so would it be easiest to use aπ SS> series of PutPixels?ππUnfortunately you don't specify which mode you're working in, soπI assume it is 320x200 (which tends to be the most popular mode here):π}ππProcedure DHL(x, y, Length : Word; Color : Byte); Assembler;π  Asmπ    mov   ax,0a000hπ    mov   es,axπ    mov   ax,yπ    shl   ax,6π    mov   di,axπ    shl   ax,2π    add   di,axπ    add   di,xπ    mov   cx,Lengthπ    mov   al,Colorπ    cldπ    rep   stosb { I bet I'll get loads of replies which uses stosw instead :) }π  End;ππProcedure DVL(x, y, Length : Word; Color : Byte); Assembler;π  Asmπ    mov   ax,0a000hπ    mov   es,axπ    mov   ax,yπ    shl   ax,6π    mov   di,axπ    shl   ax,2π    add   di,axπ    add   di,xπ    mov   al,Colorπ    mov   cx,Lengthπ@DVL1:π    mov   es:[di],alπ    add   di,320π    dec   cxπ    jnz   @DVL1π  End;ππ                                                                            7      08-24-9413:37ALL                      DAAN DE HAAS             Fast Polygons            SWAG9408    ╠ΘM    105    ╓   {πThis unit draws polygons fast. It draws only polygons which are monotoneπvertical. That means only polygons which you can fill with continues horizontalπlines. Fortunately that are the polygons which are mostly used in 3d graphics.π}ππ{*****************************************************************}π{* UnitName    : FASTPOLY.PAS                                    *}π{* Purpose     : Draw monotone vertical polygons fast            *}π{* Version     : 1.5                                             *}π{* Author      : Daan de Haas                                    *}π{* Date        : 20/10/1993                                      *}π{* Last update :  9/06/1994                                      *}π{* Language    : Borland Turbo Pascal 7.0                        *}π{* Fidonet     : Daan de Haas (2:500/104.6141)                   *}π{* Internet    : Daan.de.Haas@p6141.f104.n500.z2.fidonet.org     *}π{*****************************************************************}ππ{* VGA mode $13 and 386 processor *}π{* Literatur : Dr Dobb's XSharp   *}ππ{$R-,S-,Q-,I-}ππUNIT FastPoly;ππ{**************************} INTERFACE {**************************}ππTYPEπ  PPoint = ^TPoint;π  TPoint = RECORDπ             x,y:integer;π           END;π  PPolygon = ^TPolygon;π  PPointsList = ^TPointsList;π  TPointsList = ARRAY[0..9999] OF TPoint;π  TPolygon = RECORDπ               length,color:word;π               PointPtr:PPointsList;π             END;π  PHLine = ^THLine;π  THLine = RECORDπ             XStart,XEnd:word;π           END;π  PHLineArray = ^THLineArray;π  THLineArray = ARRAY[0..9999] OF THLine;π  THLineList = RECORDπ                 length,YStart:integer;π                 HLinePtr : PHLineArray;π               END;ππPROCEDURE HLine(x1,y1,x2:word; color:word);πPROCEDURE InitPoly(VAR p:TPolygon; len,col:word);πPROCEDURE DonePoly(VAR p:TPolygon);πPROCEDURE FillMonotoneVerticalPolygon(XOffset,YOffset:word;π                                      VertexList:TPolygon);ππCONSTπ  MaxX=320;π  MaxY=200;π  VidSegment=$A000;ππ{************************} IMPLEMENTATION {***********************}ππPROCEDURE HLine; ASSEMBLER;πASMπ  mov ax,x1             { x1 < x2 }π  cmp ax,x2π  jl  @@skip1π  je  @@lijnexitπ  xchg ax,x2π  mov  x1,axπ@@skip1:π  mov ax,maxX           { calculate y1*maxX+x1 }π  mul y1π  add ax,x1π@@1:π  mov di,ax             { dx=segment, di=offset }π  mov ax,VidSegmentππ@@skip2:π  cld                   { forward direction }π  mov cx,x2π  sub cx,x1π  inc cx                { cx = number of pixels in line }π  mov dx,diπ  add dx,cxπ  mov es,ax             { load segment register }π  mov ax,color          { get color into 386 register eax }π  mov ah,alπ  mov dx,axπ  db  $66,$c1,$e0,$10   { shl eax,16 (386 code) }π  mov ax,dxπ  test di,00000011bπ  jz @@skip             { test for doubleword border, if so jump }π@@waitdd:π  mov  es:[di],al       { put one pixel }π  inc  di               { di:=next pixel address }π  test di,00000011b     { doubleword border  ? }π  loopnz @@waitdd       { stop if cx=0 or zeroflag 1 }π  or  cx,cx             { cx=0 ? }π  jz  @@lijnexit        { if so, line is ready }π  cmp cx,4              { is a stosd possible ? }π  jl  @@waitdd          { no, then pixel after pixel }π@@skip:π  mov  dx,cxπ  shr  cx,2π  db   $f3,$66,$AB      { rep stosd (386 code) }π  mov  cx,dxπ  and cx,00000011b      { line finished ? }π  jnz @@waitddπ@@lijnexit:πEND;ππPROCEDURE ScanEdge(x1,y1,x2,y2,SetXStart,SkipFirst:integer;π                   VAR EdgePointPtr:PHLineArray); ASSEMBLER;π{ Scan converts an edge from (X1,Y1) to (X2,Y2), not including theπ point at (X2,Y2). If SkipFirst == 1, the point at (X1,Y1) isn'tπ drawn; if SkipFirst == 0, it is. For each scan line, the pixelπ closest to the scanned edge without being to the left of the scannedπ edge is chosen. Uses an all-integer approach for speed & precision.ππ Edges must not go bottom to top; that is, Y1 must be <= Y2.π Updates the pointer pointed to by EdgePointPtr to point to the nextπ free entry in the array of HLine structures. }ππVARπ  AdvanceAmt,Height:word;ππASMπ les di,EdgePointPtrπ les di,es:[di]  { point to the HLine array }π cmp SetXStart,1      { set the XStart field of each HLineπ     { struc? }π jz @@HLinePtrSet  { yes, DI points to the first XStart }π add di,2   { no, point to the XEnd field of the }π     {  first HLine struc }π@@HLinePtrSet:π mov bx,Y2π sub bx,Y1         { edge height }π jle @@ToScanEdgeExit{ guard against 0-length & horz edges }π mov Height,bx { Height = Y2 - Y1 }π sub cx,cx  { assume ErrorTerm starts at 0 (true if }π                                {  we're moving right as we draw) }π mov dx,1  { assume AdvanceAmt = 1 (move right) }π mov ax,X2π sub ax,X1           { DeltaX = X2 - X1 }π        jz      @@IsVertical   { it's a vertical edge--special case it }π jns @@SetAdvanceAmt { DeltaX >= 0 }π mov cx,1  { DeltaX < 0 (move left as we draw) }π sub cx,bx  { ErrorTerm = -Height + 1 }π neg dx  { AdvanceAmt = -1 (move left) }π        neg     ax              { Width = abs(DeltaX) }π@@SetAdvanceAmt:π mov AdvanceAmt,dxπ{ Figure out whether the edge is diagonal, X-major (more horizontal), }π{ or Y-major (more vertical) and handle appropriately. }π cmp ax,bx  { if Width==Height, it's a diagonal edge }π jz @@IsDiagonal { it's a diagonal edge--special case }π jb @@YMajor { it's a Y-major (more vertical) edge }π    { it's an X-major (more horz) edge }π        sub     dx,dx           { prepare DX:AX (Width) for division }π        div     bx  { Width/Height }π    { DX = error term advance per scan line }π mov si,ax  { SI = minimum # of pixels to advance X }π    { on each scan line }π        test    AdvanceAmt,8000h { move left or right? }π        jz      @@XMajorAdvanceAmtSet   { right, already set }π        neg     si              { left, negate the distance to advance }π    { on each scan line }π@@XMajorAdvanceAmtSet:π mov ax,X1  { starting X coordinate }π        cmp     SkipFirst,1 { skip the first point? }π        jz @@XMajorSkipEntry  { yes }π@@XMajorLoop:π mov es:[di],ax  { store the current X value }π add di,4     { point to the next HLine struc }π@@XMajorSkipEntry:π add ax,si  { set X for the next scan line }π add cx,dx  { advance error term }π jle @@XMajorNoAdvance { not time for X coord to advance one }π    { extra }π add ax,AdvanceAmt { advance X coord one extra }π        sub     cx,Height     { adjust error term back }π@@XMajorNoAdvance:π        dec     bx  { count off this scan line }π        jnz     @@XMajorLoopπ jmp @@ScanEdgeDoneπ@@ToScanEdgeExit:π jmp @@ScanEdgeExitπ@@IsVertical:π mov ax,X1 { starting (and only) X coordinate }π sub bx,SkipFirst { loop count = Height - SkipFirst }π        jz      @@ScanEdgeExit  { no scan lines left after skipping 1st }π@@VerticalLoop:π mov es:[di],ax  { store the current X value }π add di,4 { point to the next HLine struc }π dec bx  { count off this scan line }π jnz @@VerticalLoopπ jmp @@ScanEdgeDoneπ@@IsDiagonal:π mov ax,X1 { starting X coordinate }π        cmp     SkipFirst,1 { skip the first point? }π jz @@DiagonalSkipEntry { yes }π@@DiagonalLoop:π mov es:[di],ax  { store the current X value }π add di,4 { point to the next HLine struc }π@@DiagonalSkipEntry:π add ax,dx  { advance the X coordinate }π dec bx  { count off this scan line }π jnz @@DiagonalLoopπ jmp @@ScanEdgeDoneππ@@YMajor:π push bp { preserve stack frame pointer }π mov si,X1  { starting X coordinate }π        cmp     SkipFirst,1 { skip the first point? }π mov bp,bx { put Height in BP for error term calcs }π        jz @@YMajorSkipEntry { yes, skip the first point }π@@YMajorLoop:π mov es:[di],si { store the current X value }π add di,4 { point to the next HLine struc }π@@YMajorSkipEntry:π add cx,ax  { advance the error term }π jle @@YMajorNoAdvance { not time for X coord to advance }π add si,dx  { advance the X coordinate }π        sub     cx,bp  { adjust error term back }π@@YMajorNoAdvance:π        dec     bx  { count off this scan line }π        jnz     @@YMajorLoopπ pop bp  { restore stack frame pointer }π@@ScanEdgeDone:π cmp SetXStart,1 { were we working with XStart field? }π jz @@UpdateHLinePtr { yes, DI points to the next XStart  }π sub di,2  { no, point back to the XStart field }π@@UpdateHLinePtr:π        mov     bx,word ptr EdgePointPtr { point to pointer to HLine array }π mov ss:[bx],di  { update caller's HLine array pointer }π@@ScanEdgeExit:πEND;ππPROCEDURE DrawHorizontalLineList(VAR list:THLineList; color:word); ASSEMBLER;πASMπ  les si,listπ  mov cx,es:[si]                { cx = number of lines }π  mov ax,es:[si+2]              { ax = startY }π  les si,es:[si+4]              { es:si points to pointlist }π@@loop:π  mov bx,es:[si]                { get startX }π  mov dx,es:[si+2]              { get endX }π  push cx                       { save registers }π  push axπ  push siπ  push esππ  push bx                       { draw horizontal line }π  push axπ  push dxπ  mov  dx,color                 { get color }π  push dxπ  call HLineππ  pop es                        { restore registers }π  pop siπ  pop axπ  pop cxπ  inc ax                        { y:=y+1 }π  add si,4                      { next points }π  loop @@loop                   { if length=0 then stop }πEND;ππPROCEDURE FillMonotoneVerticalPolygon;πVARπ  i,MinIndex,MaxIndex,MinPoint_y,MaxPoint_y,NextIndex,π  CurrentIndex,PreviousIndex:integer;π  WorkingHLineList:THLineList;π  EdgePointPtr:PHLineArray;π  VertexPtr:PPointsList;πBEGINπ  IF VertexList.Length=0 THEN Exit;π  VertexPtr:=VertexList.PointPtr;π  MaxPoint_y:=VertexPtr^[0].y;π  MinPoint_y:=MaxPoint_y;π  MinIndex:=0;π  MaxIndex:=0;π  FOR i:=1 TO VertexList.Length-1 DOπ    WITH VerTexPtr^[i] DOπ      IF y<MinPoint_y THENπ        BEGINπ          MinPoint_y:=y;π          MinIndex:=i;π        ENDπ      ELSEπ        IF y>MaxPoint_y THENπ          BEGINπ            MaxPoint_y:=y;π            MaxIndex:=i;π          END;π  WITH WorkingHLineList DOπ    BEGINπ      length:=MaxPoint_y-MinPoint_y;π      IF length<=0 THEN Exit;π      YStart:=YOffset+MinPoint_y;π      GetMem(HLinePtr,SizeOf(THLine)*length);π      EdgePointPtr:=HLinePtr;π    END;π  CurrentIndex:=MinIndex;π  PreviousIndex:=MinIndex;π  REPEATπ    CurrentIndex:=(CurrentIndex+VertexList.length-1) MOD VertexList.length;π    ScanEdge(VertexPtr^[PreviousIndex].x+XOffset,π             VertexPtr^[PreviousIndex].y,π             VertexPtr^[CurrentIndex].x+XOffset,π             VertexPtr^[CurrentIndex].y,π             1,0,EdgePointPtr);π    PreviousIndex:=CurrentIndex;π  UNTIL CurrentIndex=MaxIndex;π  EdgePointPtr:=WorkingHLineList.HLinePtr;π  CurrentIndex:=MinIndex;π  PreviousIndex:=MinIndex;π  REPEATπ    CurrentIndex:=(CurrentIndex+1) MOD VertexList.length;π    ScanEdge(VertexPtr^[PreviousIndex].x+XOffset,π             VertexPtr^[PreviousIndex].y,π             VertexPtr^[CurrentIndex].x+XOffset,π             VertexPtr^[CurrentIndex].y,π             0,0,EdgePointPtr);π    PreviousIndex:=CurrentIndex;π  UNTIL CurrentIndex=MaxIndex;π  DrawHorizontalLineList(WorkingHLineList,VertexList.color);π  WITH WorkingHLineList DO FreeMem(HLinePtr,SizeOf(THLine)*length);πEND;ππPROCEDURE InitPoly;πBEGINπ  WITH p DOπ    BEGINπ      length:=len;π      color:=col;π      { No Error checking !}π      GetMem(PointPtr,len*SizeOf(TPoint));π    END;πEND;ππPROCEDURE DonePoly;πBEGINπ  WITH p DOπ    BEGINπ      IF PointPtr<>NIL THEN FreeMem(PointPtr,length*SizeOf(TPoint));π      PointPtr:=NIL;π    END;πEND;ππEND.ππ{*****************************************************************}π{* ProgramName : FASTPOL.PAS                                     *}π{* Purpose     : Demonstration of unit FastPoly                  *}π{* Version     : 1.0                                             *}π{* Author      : Daan de Haas                                    *}π{* Date        : 9 jun 1994                                      *}π{* Last update : 9 jun 1994                                      *}π{* Language    : Borland Pascal 7.0                              *}π{* Fidonet     : Daan de Haas (2:500/104.6141)                   *}π{* Internet    : Daan.de.Haas@p6141.f104.n500.z2.fidonet.org     *}π{*****************************************************************}ππ{$R-,I-,Q-,S-}ππUSESπ  Crt, FastPoly;ππPROCEDURE SetVideo(m:word); ASSEMBLER;πASMπ  mov ax,mπ  int $10πEND;ππPROCEDURE Polydemo;πVARπ  p1,p2:TPolygon;πBEGINπ  InitPoly(p1,6,YELLOW);π  p1.PointPtr^[0].X:=10;π  p1.PointPtr^[0].Y:=0;π  p1.PointPtr^[1].X:=20;π  p1.PointPtr^[1].Y:=0;π  p1.PointPtr^[2].X:=30;π  p1.PointPtr^[2].Y:=10;π  p1.PointPtr^[3].X:=20;π  p1.PointPtr^[3].Y:=20;π  p1.PointPtr^[4].X:=10;π  p1.PointPtr^[4].Y:=20;π  p1.PointPtr^[5].X:=0;π  p1.PointPtr^[5].Y:=10;π  InitPoly(p2,6,BLUE);π  p2.PointPtr^[0].X:=10;π  p2.PointPtr^[0].Y:=0;π  p2.PointPtr^[1].X:=20;π  p2.PointPtr^[1].Y:=0;π  p2.PointPtr^[2].X:=30;π  p2.PointPtr^[2].Y:=10;π  p2.PointPtr^[3].X:=20;π  p2.PointPtr^[3].Y:=20;π  p2.PointPtr^[4].X:=10;π  p2.PointPtr^[4].Y:=20;π  p2.PointPtr^[5].X:=0;π  p2.PointPtr^[5].Y:=10;π  REPEATπ    FillMonotoneVerticalPolygon(Random(MaxX-35),Random(MaxY-25),p1);π    FillMonotoneVerticalPolygon(Random(MaxX-35),Random(MaxY-25),p2);π  UNTIL KeyPressed;π  ReadKey;π  DonePoly(p1);π  DonePoly(p2);πEND;ππBEGINπ  ClrScr;π  Randomize;π  SetVideo($13);π  PolyDemo;π  SetVideo(3);πEND.π                                             8      08-24-9413:38ALL                      ALEX CHALFIN             Fire Graphic             SWAG9408    4[╒¿    32     ╓   {πHere is a little something for all you pyromaniacs, and demo coders out there.ππI got my hands on Jare's fire code and thought it was pretty cool, so I madeπmy own fire program. Although it didn't turn out like I thought it would (likeπJare's) what I have is (at least I think so) something that looks moreπrealistic.ππThis program was completely written by myself and was inspired by Jare's fireπcode (available on Internet FTP at ftp.eng.ufl.edu  pub/msdos/demos/programmingπ/source). A 386 computer is required (Double Word copies are used), but a 486πis highly recommended, as 28800 pixels are calculated each frame (I useπstandard mode 13h). The entire source is Pascal/Inline asm and was writtenπusing Turbo Pascal v6.0.    I hope you like it.πππ{ **** Program starts here ******** }ππProgram Phire;π{$G+}    { Enable 286 instructions }π{ coded by Phred  7/23/94     aka Alex Chalfin    }π{               Internet: achalfin@uceng.uc.edu   }π{ A fast computer is HIGHLY recommended.          }π{ Inspired by Jare's fire code                    }ππVarπ  Screen : Array[0..63999] of Byte ABSOLUTE $A000:$0000; { the VGA screen }π  VScreen : Array[0..63999] of Byte;                { an offscreen buffer }π  Lookup : Array[0..199] of Word;    { an Offset lookup table }ππProcedure SetPalette; Near;π{ Sets the Palette }ππVarπ  p : Array[0..767] of Byte;π  x : integer;ππBeginπ  for x := 0 to 255 do            { Generate fade from orange to black }π    Beginπ      p[x*3] := (x * 63) Shr 8;π      P[x*3+1] := (x * 22) Shr 8;π      P[x*3+2] := 0;π    End;π  Port[$3C8] := 0;π  For x := 0 to 255 do        { Set the palette }π    Beginπ      Port[$3C9] := P[x*3];π      Port[$3C9] := P[x*3+1];π      Port[$3C9] := P[x*3+2];π    End;πEnd;ππProcedure Burnin_Down_The_House;ππVarπ  c : Integer;ππBeginπ  Randomize;π  Repeatπ    For c := 0 to 319 do    { Setup bottom line "hot spots" }π      If Random(4) = 1π        Then VScreen[LookUp[199] + c] := Random(3) * 255;π    Asmπ      MOV  CX,28800         { Number of pixels to calculate }π      PUSH CX               { Store count on stack }π      MOV  AX,Offset VScreenπ      PUSH AX               { Store value on stack }π      MOV  SI,AXπ      MOV  BX,199π      SHL  BX,1π      MOV  AX,Word Ptr [LookUp + BX]π      ADD  SI,AXπ      DEC  SI            { DS:SI := VScreen[LookUp[198]+319] }π     @Looper:π      XOR  AX,AXπ      XOR  BX,BXπ      MOV  AL,DS:[SI+319]π      ADD  BX,AXπ      MOV  AL,DS:[SI+320]π      ADD  BX,AXπ      MOV  AL,DS:[SI+321]π      ADD  BX,AXπ      MOV  AL,DS:[SI]π      ADD  BX,AX    { Average the three pixels below and the one that its on}π      SHR  BX,2     { Divide by 4 }π      JZ  @Skipπ      DEC  BX       { Subtract 1 if value > 0 }π     @Skip:π      MOV  DS:[SI],BL  { Store pixel to screen }π      DEC  SI          { Move to next pixel }π      DEC  CXπ      JNZ @Looperπ    { Copy the screen Buffer using Double Word copies }π      MOV  BX,110π      SHL  BX,1π      MOV  AX,Word Ptr [LookUp + BX]π      MOV  DX,AXπ      POP  SI        { Restore starting offset of VScreen  }π      MOV  AX,$A000π      MOV  ES,AX     { DS:SI = starting location in buffer }π      XOR  DI,DI     { ES:DI = Starting location in screen }π      ADD  SI,DXπ      ADD  DI,DXπ      POP  CX        { Retrive Count off the stack }π      SHR  CX,2      { divide by 4 to get # of double words.              }π     db 66h          { Since TP won't allow 386 instructions, fake it.    }π      REP  MOVSW     { This translates into REP MOVSD (move double words) }π    End;π  Until Port[$60] = 1;   { Until ESC is pressed }πEnd;ππBeginπ  Asm              { Initialize mode 13h VGA mode }π    MOV  AX,13hπ    INT  10hπ  End;π  For LookUp[0] := 1 to 199 do            { Calculate lookup table }π    LookUp[LookUp[0]] := LookUp[0] * 320;π  LookUp[0] := 0;π  SetPalette;π  FillChar(VScreen, 64000, 0);π  Burnin_Down_The_House;π  Asmπ    MOV  AX,3π    INT  10hπ  End;πEnd.ππ                                               9      08-24-9413:40ALL                      FRED JOHNSON             FONTS WITH TURBOPASCAL V7SWAG9408    ù┤ƒì    19     ╓   π{compile the *.bgi and *.chr files into a .exe file?  If so how?ππ1. Collect all the fonts you canπ   If you don't have them all, fake it (use old one in place of real one)π2. Compile them separately into OBJ filesπ   example: binobj bold.chr bold.obj boldππ3. DO the BGI driver for your video card.π   example: binobj egavga.bgi egavga.obj egavgaππ4. use the TPUs in your main progπ5. Load the video driver like an external procedure;πππ{-------------------------------example 1 (converts chr->obj->tpu)}ππunit boldfont;   {use the name + font for all of the fonts}ππinterfaceπprocedure bold;πimplementationπprocedure bold; external;π{$L bold.obj}πend.π{------------------------------------------------------------------------}ππ{--------------------------------example 2}πuses graph,π   boldfont, eurofont, gothfont, lcomfont, littfont,π   sansfont, simpfont, scrifont, tripfont, tscrfont;ππprocedure egavga; external;π{$L egavga.obj}ππconstπ   xFonts : array[0..10] of recordπ      sFontName  : string;π      xpFontAddr : pointer;π   end =π   ( {Fonts must remain in this order because of settextstyle()}π   (sFontName :'Default'; xpFontAddr : nil),  {style 00}π   (sFontName :'Triplex'; xpFontAddr : @TRIP),{style 01}π   (sFontName :'Small';   xpFontAddr : @LITT),{style 02}π   (sFontName :'Sans';    xpFontAddr : @SANS),{style 03}π   (sFontName :'Gothic';  xpFontAddr : @GOTH),{style 04}π   (sFontName :'Script';  xpFontAddr : @SCRI),{style 05}π   (sFontName :'Simplex'; xpFontAddr : @SIMP),{style 06}π   (sFontName :'Tscr';    xpFontAddr : @TSCR),{style 07}π   (sFontName :'Lcom';    xpFontAddr : @LCOM),{style 08}π   (sFontName :'Euro';    xpFontAddr : @EURO),{style 09}π   (sFontName :'Bold';    xpFontAddr : @BOLD) {style 10}π   );ππvarπ   gd, gm, i : integer;ππbeginπ   if RegisterBGIDriver(@EGAVGA) < 0 then halt;π   for i := 1 to 10 doπ      if RegisterBGIFont(xFonts[i].xpFontAddr) < 0 thenπ         write('Can''t register', xFonts[i].sFontName,' font');ππ   gd := VGA;π   gm := VGAHi;π   initgraph(gd, gm, '');ππ   for i := 0 to 10 doπ      beginπ         settextstyle(i,0,10);π         outtextxy(10,20,xFonts[i].sFontName);π         readln;π         cleardevice;π      end;π   closegraph;πend.π                                                                                              10     08-24-9413:40ALL                      DAVID DANIEL ANDERSON    Gif info display         SWAG9408    ▓ÆA╨    36     ╓   {πBS> Can anone out there tell me where you get the resoloution out of a Gif fileπBS> from? What I am saying is, I would like to make a program to look at a GifπBS> and grab the resoloution out of it for my dir list files. Any help would beπBS> appreciated.ππI've written a freeware program to do just this.  Program name is GRR,πand Pascal source accompanies it.  Here is the source from the latestπ(and only) version.  I apologize for the lack of comments, but it isπrather straightforward, I think. }ππprogram getGIFheader;πusesπ  dos;πconstπ  progdata = 'GRR- Free DOS utility: GIF file info displayer.';π  progdat2 =π  'V1.00: August 19, 1993. (c) 1993 by David Daniel Anderson - Reign Ware.';π  usage =π  'Usage:  GRR directory and/or file_spec[.GIF]   Example:  GRR cindyc*';πvarπ  header : string[6];π  gpixn : byte;π  gpixels, gback, rwidthLSB, rheightLSB, rwidth, rheight : char;π  gifname : string[12];π  giffile : text;π  dirinfo : searchrec;π  gpath : pathstr;π  gdir : dirstr;π  gname : namestr;π  gext : extstr;ππprocedure showhelp;πbegin {-- showhelp --}π  writeln(progdata);π  writeln(progdat2);π  writeln(usage);π  halt;πend {-- showhelp --};ππfunction taffy(astring : string; newlen : byte) : string;πbegin {-- taffy --}π  while (length(astring) < newlen) doπ    astring := astring + ' ';π  taffy := astring;πend {-- taffy --};ππfunction LeadingZero(w : Word) : string;πvarπ  s : string;πbegin {-- LeadingZero --}π  Str(w : 0, s);π  if (length(s) = 1) thenπ    s := '0' + s;π  LeadingZero := s;πend {-- LeadingZero --};ππprocedure writeftime(fdatetime : longint);πvarπ  Year2 : string;π  DateTimeInf : DateTime;πbegin {-- writeftime --}π  UnpackTime(fdatetime, DateTimeInf);π  with DateTimeInf doπ  beginπ  Year2 := LeadingZero(Year);π  Delete(Year2, 1, 2);π  Write(LeadingZero(Month), '-', LeadingZero(Day), '-', Year2, '  ',π  LeadingZero(Hour), ':', LeadingZero(Min), ':', LeadingZero(Sec));π  end;πend {-- writeftime --};πππprocedure displaygifscreenstats(screendes : byte);πvarπ  GCM : Boolean;πbegin {-- displaygifscreenstats --}π  GCM := screendes > 128;π  if (screendes > 128) thenπ    screendes := screendes - 128;π  if (screendes > 64) thenπ    screendes := screendes - 64;π  if (screendes > 32) thenπ    screendes := screendes - 32;π  if (screendes > 16) thenπ    screendes := screendes - 16;π  if (screendes > 8) thenπ    screendes := screendes - 8;π  case (screendes) ofπ    0: Write('  2');π    1: Write('  4');π    2: Write('  8');π    3: Write(' 16');π    4: Write(' 32');π    5: Write(' 64');π    6: Write('128');π    7: Write('256');π  end {-- CASE --};π  if (GCM) thenπ    Write(' ]  GCM/')π  elseπ    Write(' ]  ---/');πend {-- displaygifscreenstats --};ππprocedure checkforgiflite(var thefile : text);πvarπ  ic : Word;π  dummy, glite : char;π  gliteword : string[7];πbegin {-- checkforgiflite --}π  for ic := 13 to 784 doπ    read(thefile, dummy);π  gliteword := '       ';π  for ic := 1 to 7 doπ    beginπ    read(thefile, glite);π    gliteword[ic] := glite;π    end;π  if (pos('GIFLITE', gliteword) = 1) thenπ    Write('GL')π  elseπ    Write('--');πend {-- checkforgiflite --};ππbegin {-- getGIFheader --}π  gpath := '';π  gpath := paramstr(1);π  if (gpath = '') thenπ    gpath := '*.gif';π  if (pos('.', gpath) <> 0) thenπ    beginπ    gpath := copy(gpath, 1, pos('.', gpath));π    gpath := gpath + 'gif'π    endπ  elseπ    gpath := gpath + '*.gif';π  fsplit(fexpand(gpath), gdir, gname, gext);π  findfirst(gpath, archive, dirinfo);π  if (doserror <> 0) thenπ    showhelp;π  while (doserror = 0) doπ    beginπ    gifname := dirinfo.name;π    assign(giffile, gdir + gifname);π    reset(giffile);π    read(giffile, header);π    if (pos('GIF', header) <> 1) thenπ      header := '?_GIF?';π    read(giffile, rwidthLSB, rwidth, rheightLSB, rheight, gpixels, gback);π    gifname := taffy(gifname, 12);π    Write(gifname, '  ', dirinfo.size:7, '  ');π    writeftime(dirinfo.time);π    Write('    ', header, '   [');π    Write((ord(rwidthLSB) + (256 * ord(rwidth))):4, ' ',π         (ord(rheightLSB) + (256 * ord(rheight))):4, '  ');π    gpixn := ord(gpixels);π    displaygifscreenstats(gpixn);π    {         write ( ', ', ord ( gback )); }π    { This is the background color, commented out since it is not used }π    checkforgiflite(giffile);π    writeln;π    close(giffile);π    findnext(dirinfo);π    end;πend {-- getGIFheader --}.π                                                                                                              11     08-24-9413:41ALL                      ERIC MILLER              Graphic Compression      SWAG9408    ╫'∙U    10     ╓   {π TW> I'll need an algorithm to make a graphic smaller.ππ TW> I will read a 640x480x256 and want to make it a smaller size.π TW> For example 80x60x256 or 160x120x256 or something else.π TW> Maybe someone could send me an algorithm or a sample.ππ   If you simply want a smaller version of the original image, thenπ   it's easy.ππ  ie, for 640x480 to 160x120 ( 1/4 original size)π}ππ  FOR Y := 0 TO 119 { 160x120 Y axis }π    BEGINπ      NewY := (Y * 4);  { corresponding point on 640x480 Y axis }π      FOR X := 0 TO 159 DO  { 160x120 X axis }π        BEGINπ          NewX := (X * 4); { corresponding point on 640x480 X axis }π          Image160x120[Y, X] := Image640x480[NewY, NewX];π        END;π    END;ππ  See, simply multiply each point in 160x120 by 4 to get correspondingπ  point in 640x480.  This of course skips all pixels in between...π  Also, the in the example above, note that you cannot haveπ  an array of [0..479, 0..639] of Byte!  I just put that in thereπ  to show how it is done.ππ  Eric Millerπ  mysticm@ephsa.sat.tx.usπ                                                                                                                 12     08-24-9413:42ALL                      PAUL BROMAN              Pallete Handling         SWAG9408    g├v6    53     ╓   { GrafCont initializes the graphics mode and handles pallete fades. }ππunit GrafCont;ππinterfaceππusesπ  Crt, Dos, Graph;ππtypeπ  Palette256 = array[0..255, 0..2] of Byte;π  Palette16 = array[0..15, 0..2] of Byte;ππvarπ  Mode           : byte;ππprocedure Init256VGA;πprocedure Init16VGA;πprocedure SetVGAPalette256(PalBuf: Palette256);πprocedure GetVGAPalette256(var PalBuf: Palette256);πprocedure SetVGAPalette16(PalBuf: Palette16);πprocedure GetVGAPalette16(var PalBuf: Palette16);πprocedure GetRGBPalette(PalNum: integer; var R, G, B: byte);πprocedure FadeOutScreen256;πprocedure FadeOutScreen16;πprocedure FadeInScreen256(PalToMake: Palette256);πprocedure FadeInScreen16(PalToMake: Palette16);ππimplementationππprocedure Init256VGA;π   {This procedure relies on BGI drivers obtained for Pascal.π    You may need to create a new procedure based on your ownπ    method for turning on the graphics mode.}ππ   varπ     graphmode      : integer;π     graphdriver    : integer;ππ   beginπ   graphdriver := VGA256Graph;  {Defined as an OBJ}π   graphmode := 0;π   initgraph(graphdriver, graphmode, '');π   end;ππprocedure Init16VGA;π   varπ     graphdriver    : integer;π     graphmode      : integer;ππ   beginπ   graphdriver := 9;π   graphmode := 2;π   initgraph(graphdriver, graphmode, '');π   end;ππprocedure SetVGAPalette256;πvarπ  ColorOn : byte;ππbeginπ  Port[$3C8] := 0;π  for ColorOn := 0 to 255 doπ      beginπ      Port[$3C9] := PalBuf[ColorOn, 0];π      Port[$3C9] := PalBuf[ColorOn, 1];π      Port[$3C9] := PalBuf[ColorOn, 2];π      end;πend;ππprocedure GetVGAPalette256;πvarπ  ColorOn : byte;ππbeginπ  Port[$3C8] := 1;π  for ColorOn := 0 to 255 doπ      beginπ      PalBuf[ColorOn, 0] := Port[$3C9];π      PalBuf[ColorOn, 1] := Port[$3C9];π      PalBuf[ColorOn, 2] := Port[$3C9];π      end;π  PalBuf[0, 0] := 0;π  PalBuf[0, 1] := 0;π  PalBuf[0, 2] := 0;πend;ππprocedure SetVGAPalette16;πvarπ  ColorOn : byte;ππbeginπ  Port[$3C8] := 0;π  for ColorOn := 0 to 15 doπ      beginπ      Port[$3C9] := PalBuf[ColorOn, 0];π      Port[$3C9] := PalBuf[ColorOn, 1];π      Port[$3C9] := PalBuf[ColorOn, 2];π      end;πend;ππprocedure GetVGAPalette16;πvarπ  ColorOn : byte;ππbeginπ  Port[$3C8] := 1;π  for ColorOn := 0 to 15 doπ      beginπ      PalBuf[ColorOn, 0] := Port[$3C9];π      PalBuf[ColorOn, 1] := Port[$3C9];π      PalBuf[ColorOn, 2] := Port[$3C9];π      end;π  PalBuf[0, 0] := 0;π  PalBuf[0, 1] := 0;π  PalBuf[0, 2] := 0;πend;πππprocedure GetRGBPalette;ππbeginπ  Port[$3C8] := PalNum;π  R := Port[$3C9];π  G := Port[$3C9];π  B := Port[$3C9];πend;ππprocedure FadeOutScreen256;π   varπ     Count        : word;π     ColorOn      : byte;π     PalToMake    : Palette256;π     PaletteStuff : Palette256;ππ   beginπ   GetVGAPalette256(PaletteStuff);π   PalToMake := PaletteStuff;π   for Count := 63 downto 0 doπ       beginπ       Port[$3C8] := 0;π       PaletteStuff := PalToMake;π       Delay(1);π       for ColorOn := 0 to 255 doπ           beginπ           PaletteStuff[ColorOn, 0] := (PaletteStuff[ColorOn, 0] * Count) div 63;π           PaletteStuff[ColorOn, 1] := (PaletteStuff[ColorOn, 1] * Count) div 63;π           PaletteStuff[ColorOn, 2] := (PaletteStuff[ColorOn, 2] * Count) div 63;π           Port[$3C9] := PaletteStuff[ColorOn, 0];π           Port[$3C9] := PaletteStuff[ColorOn, 1];π           Port[$3C9] := PaletteStuff[ColorOn, 2];π           end;π       end;π   end;ππprocedure FadeOutText;π   varπ     Count        : word;π     ColorOn      : byte;π     PalToMake    : Palette256;π     PaletteStuff : Palette256;ππ   beginπ   GetVGAPalette256(PaletteStuff);π   PalToMake := PaletteStuff;π   for Count := 63 downto 0 doπ       beginπ       Port[$3C8] := 0;π       PaletteStuff := PalToMake;π       Delay(20);π       for ColorOn := 0 to 255 doπ           beginπ           PaletteStuff[ColorOn, 0] := (PaletteStuff[ColorOn, 0] * Count) div 63;π           PaletteStuff[ColorOn, 1] := (PaletteStuff[ColorOn, 1] * Count) div 63;π           PaletteStuff[ColorOn, 2] := (PaletteStuff[ColorOn, 2] * Count) div 63;π           Port[$3C9] := PaletteStuff[ColorOn, 0];π           Port[$3C9] := PaletteStuff[ColorOn, 1];π           Port[$3C9] := PaletteStuff[ColorOn, 2];π           end;π       end;π   end;ππprocedure FadeInScreen256;π   varπ     Count        : byte;π     ColorOn      : byte;π     PaletteStuff : Palette256;π     FastPal      : Palette256;ππ   beginπ   GetVGAPalette256(PaletteStuff);π   for Count := 0 to 63 doπ       beginπ       Port[$3C8] := 0;π       PaletteStuff := PalToMake;π       Delay(1);π       for ColorOn := 0 to 255 doπ           beginπ           PaletteStuff[ColorOn, 0] := (PaletteStuff[ColorOn, 0] * Count) div 63;π           PaletteStuff[ColorOn, 1] := (PaletteStuff[ColorOn, 1] * Count) div 63;π           PaletteStuff[ColorOn, 2] := (PaletteStuff[ColorOn, 2] * Count) div 63;π           Port[$3C9] := PaletteStuff[ColorOn, 0];π           Port[$3C9] := PaletteStuff[ColorOn, 1];π           Port[$3C9] := PaletteStuff[ColorOn, 2];π           end;π       end;π   end;ππprocedure FadeOutScreen16;π   varπ     Count        : word;π     ColorOn      : byte;π     PalToMake    : Palette16;π     PaletteStuff : Palette16;ππ   beginπ   GetVGAPalette16(PaletteStuff);π   PalToMake := PaletteStuff;π   for Count := 63 downto 0 doπ       beginπ       Port[$3C8] := 0;π       PaletteStuff := PalToMake;π       Delay(5);π       for ColorOn := 0 to 15 doπ           beginπ           PaletteStuff[ColorOn, 0] := (PaletteStuff[ColorOn, 0] * Count) div 63;π           PaletteStuff[ColorOn, 1] := (PaletteStuff[ColorOn, 1] * Count) div 63;π           PaletteStuff[ColorOn, 2] := (PaletteStuff[ColorOn, 2] * Count) div 63;π           Port[$3C9] := PaletteStuff[ColorOn, 0];π           Port[$3C9] := PaletteStuff[ColorOn, 1];π           Port[$3C9] := PaletteStuff[ColorOn, 2];π           end;π       end;π   end;ππprocedure FadeInScreen16;π   varπ     Count        : byte;π     ColorOn      : byte;π     PaletteStuff : Palette16;π     FastPal      : Palette16;ππ   beginπ   GetVGAPalette16(PaletteStuff);π   for Count := 0 to 63 doπ       beginπ       Port[$3C8] := 0;π       PaletteStuff := PalToMake;π       Delay(5);π       for ColorOn := 0 to 15 doπ           beginπ           PaletteStuff[ColorOn, 0] := (PaletteStuff[ColorOn, 0] * Count) div 63;π           PaletteStuff[ColorOn, 1] := (PaletteStuff[ColorOn, 1] * Count) div 63;π           PaletteStuff[ColorOn, 2] := (PaletteStuff[ColorOn, 2] * Count) div 63;π           Port[$3C9] := PaletteStuff[ColorOn, 0];π           Port[$3C9] := PaletteStuff[ColorOn, 1];π           Port[$3C9] := PaletteStuff[ColorOn, 2];π           end;π       end;π   end;ππend.ππ                 13     08-24-9413:46ALL                      GARTH KRUMINS            MODE-X Routines          SWAG9408    ╬å2    17     ╓   {π JW> What is mode-x or ($13) or whatever in graphics.  I like to writeπ     Mode-x is just your 320x200x256 VGA graphics mode.ππIt's pretty similar to using pascal's graph unit, except you don't!  You haveπto get all the procedures and functions set-up yourself.π}ππPROCEDURE InitVGA; ASSEMBLER;  {Puts you in 320x200x256 VGA}πasm π   mov  ax, 13h π   int  10h πend; π πPROCEDURE InitTEXT; ASSEMBLER; {Puts you back in 80x25 text mode} πasm π   mov  ax, 03h π   int  10h πend; ππPROCEDURE SetColor (ColorNo, Red, Green, Blue : byte); πbegin     {Changes the pallete data for a particular colour} π     PORT[$3C8] := ColorNo; π     PORT[$3C9] := Red; π     PORT[$3C9] := Green; π     PORT[$3C9] := Blue; πend; π πPROCEDURE MovCursor (X,Y : byte);  {Moves the cursor to (X,Y)} πbegin π  asm π  MOV   ah, 02h π  XOR   bx, bx π  MOV   dh, Y π  MOV   dl, X π  INT   10h π  end; πend; π πFUNCTION ReadCursorX: byte; assembler;  {Get X position of cursor}πasm π  MOV   ah, 03h π  XOR   bx, bx π  INT   10h π  MOV   al, dl πend; π πFUNCTION ReadCursorY: byte; assembler;  {Get Y position of cursor} πasm π  MOV   ah, 03h π  XOR   bx, bx π  INT   10h π  MOV   al, dh πend; π πPROCEDURE PutText (TextData : string; Color : byte);  {Write a string} πvar      {It's not the fastest way to do it, but it does the job} π z, ASCdata, CursorX, CursorY : byte; πbegin π CursorX := ReadCursorX;π CursorY := ReadCursorY; π for z := 1 to Length(TextData) do π begin π  ASCdata := Ord(TextData[z]); π  asm π  MOV   ah, 0Ah π  MOV   al, ASCdata π  XOR   bx, bx π  MOV   bl, Color π  MOV   cx, 1 π  INT   10h π  end; π  inc(CursorX); π  if CursorX=40 then begin CursorX:=0; inc(CursorY); end; π  MovCursor(CursorX,CursorY); π end; πend; π πPROCEDURE PlotPixel(X, Y: Word; Color: Byte); ASSEMBLER; {Plots a pixel} πasmπ   push es π   push di π   mov  ax, Y π   mov  bx, ax π   shl  ax, 8 π   shl  bx, 6 π   add  ax, bx π   add  ax, X π   mov  di, ax π   mov  ax, $A000 π   mov  es, ax π   mov  al, Color π   mov  es:[di], al π   pop  diπ   pop  esπend;π                 14     08-24-9413:50ALL                      JAMES COOK               Pcx Viewer!              SWAG9408    φE:]    30     ╓   πUses Crt;π{ Sample program to display a 320x200x256 PCX inπ  mode 13h.  PCX source copied from MCGA07, a MCGAπ  graphics unit written by James Cook in his MCGAπ  programming tutorial on Quantum Leap BBS }ππTYPEπ  TPalette = array[0..767] of Byte;π  PalettePtr = ^TPalette;π{ PCX stuff }π  PCXHeaderPtr=  ^PCXHeader;π  PCXHeader   =  recordπ                   Signature      :  Char;π                   Version        :  Char;π                   Encoding       :  Char;π                   BitsPerPixel   :  Char;π                   XMin,YMin,π                   XMax,YMax      :  Integer;π                   HRes,VRes      :  Integer;π                   Palette        :  Array [0..47] of byte;π                   Reserved       :  Char;π                   Planes         :  Char;π                   BytesPerLine   :  Integer;π                   PaletteType    :  Integer;π                   Filler         :  Array [0..57] of byte;π                 end;ππProcedure ExtractLineASM (BytesWide:Integer;Var Source,Dest:Pointer);πvarπ  DestSeg,π  DestOfs,π  SourceSeg,π  SourceOfs   :  Word;πbeginπ  SourceSeg := Seg (Source^);π  SourceOfs := Ofs (Source^);π  DestSeg   := Seg (Dest^);π  DestOfs   := Ofs (Dest^);ππ  asmπ    push  dsπ    push  siππ    cldππ    mov   ax,DestSegπ    mov   es,axπ    mov   di,DestOfs     { es:di -> destination pointer }π    mov   ax,SourceSegπ    mov   ds,axπ    mov   si,SourceOfs   { ds:si -> source buffer }ππ    mov   bx,diπ    add   bx,BytesWide   { bx holds position to stop for this row }π    xor   cx,cxππ  @@GetNextByte:π    cmp   bx,di          { are we done with the line }π    jbe   @@ExitHereππ    lodsb                { al contains next byte }ππ    mov   ah,alπ    and   ah,0C0hπ    cmp   ah,0C0hππ    jne    @@SingleByteπ                         { must be a run of bytes }π    mov   cl,alπ    and   cl,3Fhπ    lodsbπ    rep   stosbπ    jmp   @@GetNextByteππ  @@SingleByte:π    stosbπ    jmp   @@GetNextByteππ  @@ExitHere:π    mov   SourceSeg,dsπ    mov   SourceOfs,siπ    mov   DestSeg,esπ    mov   DestOfs,diππ    pop   siπ    pop   dsπ  end;ππ  Source := Ptr (SourceSeg,SourceOfs);π  Dest   := Ptr (DestSeg,DestOfs);πend;ππProcedure DisplayPCX (X,Y:Integer;Buf:Pointer);πvarπ  I,NumRows,π  BytesWide   :  Integer;π  Header      :  PCXHeaderPtr;π  DestPtr     :  Pointer;π  Offset      :  Word;ππbeginπ  Header    := Ptr (Seg(Buf^),Ofs(Buf^));π  Buf       := Ptr (Seg(Buf^),Ofs(Buf^)+128);π  Offset    := Y * 320 + X;π  NumRows   := Header^.YMax - Header^.YMin + 1;π  BytesWide := Header^.XMax - Header^.XMin + 1;π  If Odd (BytesWide) then Inc (BytesWide);ππ  For I := 1 to NumRows do beginπ    DestPtr := Ptr ($A000,Offset);π    ExtractLineASM (BytesWide,Buf,DestPtr);π    Inc (Offset,320);π    end;πend;π{ end PCX stuff }ππProcedure Graph13h; assembler;πasmπ  mov al,$13π  mov ah,0π  int 10hπend;ππVARπ  F: File;           { PCX file }π  Hdr: PCXHeaderPtr; { PCX header structure & file }π  Pal: PalettePtr;   { PCX palette }π  Shade, Size: Word; { RGB shade, file size }ππBEGINπ  Graph13h;                          { set mode 13h }π  Assign(F, 'filename.pcx');         { open PCX file }π  Reset(F,1);π  Size := FileSize(F);π  GetMem(Hdr, Size);                 { load PCX into memory }π  Blockread(F, Hdr^, Size);π  Close(F);π  Pal := Ptr( Seg(Hdr^), Ofs(Hdr^) + Size - 768);    { get palette location }π  Port[968] := 0;                                    { set palette }π  FOR Shade := 0 TO 767 DOπ    Port[969] := Pal^[Shade] SHR 2;π  DisplayPCX(0, 0, Hdr);                             { decode PCX to screen }π  WHILE Readkey <> #13 DO;                           { wait for return key }π  TextMode(CO80);πEND.π                                                   15     08-24-9413:50ALL                      OLAF BARTELT             Vga 256 Color PCX        SWAG9408    ┘*ô    22     ╓   {π CF> I am working with VGA 320x200x256.  Can anyone please helpπ CF> me with a good line routine and the PCX format?  I haveπ CF> tryed both and things go bad.. If you have code layingπ CF> around it would help me a lot...  Thanksππ}ππPROCEDURE load_pcx(dx, dy : WORD; name : STRING);πVAR q                          : FILE;        { Quellendatei-Handle         }π    b                          : ARRAY[0..2047] OF BYTE;  { Puffer          }π    anz, pos, c, w, h, e, pack : WORD;        { diverse benötigte Variablen }π    x, y                       : WORD;        { für die PCX-Laderoutine     }ππLABEL ende_background;                        { Sprungmarken definieren     }ππBEGINπ  x := dx; y := dy;                           { Nullpunkt festsetzen        }ππ  ASSIGN(q, name); {$I-} RESET(q, 1); {$I+}   { Quellendatei öffnen         }π  IF IORESULT <> 0 THEN                       { Fehler beim Öffnen?         }π    GOTO ende_background;                     { Ja: zum Ende springen       }ππ  BLOCKREAD(q, b, 128, anz);                  { Header einlesen             }ππ  IF (b[0] <> 10) OR (b[3] <> 8) THEN         { wirklich ein PCX-File?      }π  BEGINπ    CLOSE(q);                                 { Nein: Datei schließen und   }π    GOTO ende_background;                     {       zum Ende springen     }π  END;ππ  w := SUCC((b[9] - b[5]) SHL 8 + b[8] - b[4]);  { Breite auslesen          }π  h := SUCC((b[11] - b[7]) SHL 8 + b[10] - b[6]);  { Höhe auslesen          }ππ  pack := 0; c := 0; e := y + h;π  REPEATπ    BLOCKREAD(q, b, 2048, anz);ππ    pos := 0;π    WHILE (pos < anz) AND (y < e) DOπ    BEGINπ      IF pack <> 0 THENπ      BEGINπ        FOR c := c TO c + pack DOπ          MEM[SEGA000:y*320+(x+c)] := b[pos];π        pack := 0;π      ENDπ      ELSEπ        IF (b[pos] AND $C0) = $C0 THENπ          pack := b[pos] AND $3Fπ        ELSEπ        BEGINπ          MEM[SEGA000:y*320+(x+c)] := b[pos];π          INC(c);π        END;ππ      INC(pos);π      IF c = w THEN                           { letzte Spalte erreicht?     }π      BEGINπ        c := 0;                               { Ja: Spalte auf 0 setzen und }π        INC(y);                               {     in die nächste Zeile    }π      END;π    END;π  UNTIL (anz = 0) OR (y = e);ππ  SEEK(q, FILESIZE(q) - 3 SHL 8 - 1);π  BLOCKREAD(q, b, 3 SHL 8 + 1);ππ  IF b[0] = 12 THENπ    FOR x := 1 TO 3 SHL 8 + 1 DOπ      b[x] := b[x] SHR 2;ππ  PORT[$3C8] := 0;ππ  FOR x := 0 TO 255 DOπ  BEGINπ    PORT[$3C9] := b[x*3+1];π    PORT[$3C9] := b[x*3+2];π    PORT[$3C9] := b[x*3+3];π  END;ππ  CLOSE(q);ππende_background:πEND;ππBEGINπ    Load_Pcx(1,1,'c:\lpexface.pcx');πEND.                                            16     08-24-9413:50ALL                      ANDREW EIGUS             Pcx Bitmap Rotating      SWAG9408    tôp    127    ╓   { ROTATE.PAS }ππ{π  Rotating textured surface.π  Coded by Mike Shirobokov(MSH) aka Mad Max / Queue members.π  You can do anything with this code until this commentsπ  remain unchanged.ππ  Bugs corrected by Alex Grischenkoπ}ππ{$G+,A-,V-,X+}π{$M 16384,0,16384}ππuses Crt, Objects, Memory, VgaGraph;  { unit code at the end of program }ππconstπ{ Try to play with this constants }π  RotateSteps  = {64*5}65*10;π  AngleStep    = {3}1;π  MoveStep     = {10}1;π  ScaleStep    : Real =  0.02;ππtypeπ  TBPoint = record X,Y: { Byte} Integer; end;π  TPointArray = array[ 1..500 ] of TBPoint;ππ  TRotateApp = object(TGraphApplication)π    StartTime,π    FramesNumber:LongInt;π    {Texture: TImage;}π    X,Y    : Integer;π    WSX,WSY: Integer;π    WSXR,π    WSYR   : Real;π    Angle  : Integer;π    Size   : TPoint;π    CurPage: Integer;π    Texture: TImage;π    constructor Init;π    procedure Run;      virtual;π    destructor Done;    virtual;π    procedure Draw;     virtual;π    procedure FlipPage; virtual;π    procedure Rotate( AngleStep: Integer );π    procedure Move( DeltaX, DeltaY: Integer );π    procedure Scale( Factor: Real );π    procedure Update;π  end;πvarπ  Pal:  TRGBPalette;π  Time:  LongInt absolute $0:$46C;ππprocedure TRotateApp.FlipPage;πbeginπ  CurPage := 1-CurPage;π  ShowPage(1-CurPage);πend;ππconstructor TRotateApp.Init;πvarπ  I, J: Integer;πbeginπ  if not inherited Init(True) or not Texture.Load( ParamStr(1) ) then Fail;π  SetPalette( Texture.Palette );π  X := 0;π  Y := 0;π  WSX := 240;π  WSY := 360;π  WSXR := WSX;π  WSYR := WSY;π  Angle := 0;π  Size.X := HRes div 2;π  Size.Y := VRes div 2;π  FramesNumber := 0;π  StartTime := Time;  {     asm mov ax,13h; int 10h; end;}π  system.move (Texture.Data^,Screen,64000);π    SetPalette( Texture.Palette );π{  readkey;}πend;ππprocedure TRotateApp.Rotate( AngleStep: Integer );πbeginπ  Inc( Angle, AngleStep );π  Angle := Angle mod RotateSteps;πend;ππprocedure TRotateApp.Move( DeltaX, DeltaY: Integer );πbeginπ  Inc( X, DeltaX );π  Inc( Y, DeltaY );πend;ππprocedure TRotateApp.Scale( Factor: Real );πbeginπ  WSXR := WSXR*Factor;π  WSX := Round(WSXR);π  WSYR := WSYR*Factor;π  WSY := Round(WSYR);πend;ππprocedure TRotateApp.Update;πbeginπ  Move( MoveStep, MoveStep );π  Rotate(AngleStep);π  Scale(1+ScaleStep);π  if (WSY >= 2000) or (WSY<=100) then ScaleStep := -ScaleStep;πend;ππprocedure TRotateApp.Draw;ππvarπ  I :  Integer;π  Border,π  LineBuf: TPointArray;π  BorderLen: Integer;π  X1RN,X1LN,π  Y1RN,Y1LN,π  X2RN,X2LN,π  Y2RN,Y2LN,π  X1R,X1L,π  Y1R,Y1L,π  X2R,X2L,π  Y2R,Y2L,π  XL,YL: Integer;ππ{ This function can be heavly optimized but I'm too lazy to do absoletelyπ  meaningless things :-) }πfunction BuildLine( var Buffer: TPointArray; X1,Y1, X2,Y2: Integer;π      Len: Integer ): Integer;πvarπ  I: Word;π  XStep,π  YStep: LongInt;πbeginπ  XStep := (LongInt(X2-X1) shl 16) div Len;π  YStep := (LongInt(Y2-Y1) shl 16) div Len;π  for I := 1 to Len doπ  beginπ    Buffer[I].X := Integer( ((XStep*I) shr 16) - ((XStep*(I-1)) shr 16) );π    Buffer[I].Y := Integer( ((YStep*I) shr 16) - ((YStep*(I-1)) shr 16) );π  end;πend;ππprocedure DrawPicLine( var Buffer; BitPlane: Integer;π        StartX, StartY: Integer; Len: Integer; var LineBuf );πvarπ  PD :  Pointer;πbeginπ  PD := Texture.Data;           { pointer to unpacked screen image }π  Port[$3C4] := 2;π  if BitPlane = 0 thenπ    Port[$3C5] := 3π  elseπ    Port[$3C5] := 12;ππ  asmπ    push  dsπ    mov   bx,[StartX]             { bx = StartX }π    mov   dx,[StartY]             { dx = StartY }π    les   di,Buffer               { ES:DI = @Screen }π    add   di,VPageLen/2-Hres/4    { calc target page }π    mov   cx,Len                  { Drawing buffer length }π    lds   si,PD                   { DS:SI = pointer to data }π    push  bp                      { store BP }π    mov   bp,word ptr LineBuf     { BP = offset LineBuf }π    cldπ@loop:π      PUSH DXπ      MOV  AX,320π      MUL  DX                     { AX = StartY*320 }π      POP  DXππ      PUSH BXπ      ADD  BX,AXπ      mov  al,[bx+SI]π      POP  BXππ      stosbπ      sub  di,HRes/4+1{ add di,hres-1}π      add  BX,[bp]π      ADD  bp,2π      add  DX,[bp]π      ADD  bp,2ππ{      CMP  BX,320π      JB   @@1π      XOR  BX,BXπ@@1:  CMP  DX,200π      JB   @@2π      XOR  DX,DXπ@@2:}π      loop @loopππ      pop bpπ      pop dsπ  end;πend;ππbeginππ{ Just imagine what can be if the next 8 lines would be more complex.π  I'm working around it. }π{π     (X1L,Y1L)        (X2R,Y1R)π        +---------------+π        |               |π        |               |π        |               |π        +---------------+π     (X2L,Y2L)        (X2R,Y2R)ππ     (X1LN,Y1LN)        (X2RN,Y1RN)π        +---------------+π        |               |π        |               |π        |               |π        +---------------+π     (X2LN,Y2LN)        (X2RN,Y2RN)ππ}π  X1L := 0;π  Y1L := 0;π  X2L := 0;π  Y2L := WSY;π  X1R := WSX;π  Y1R := 0;π  X2R := WSX;π  Y2R := WSY;π{ I call Cos and Sin instead of using tables!? Yeah, I do. So what?π  See comments near BuildLine ;-) }π{  I just rotate the rectangle corners, but why I do no more? }π  X1RN := Round(π(X1R*Cos(2*Pi/RotateSteps*Angle)+Y1R*Sin(2*Pi/RotateSteps*Angle)) );π  Y1RN := Round(π(Y1R*Cos(2*Pi/RotateSteps*Angle)-X1R*Sin(2*Pi/RotateSteps*Angle)) );π  X1LN := Round(π(X1L*Cos(2*Pi/RotateSteps*Angle)+Y1L*Sin(2*Pi/RotateSteps*Angle)) );π  Y1LN := Round(π(Y1L*Cos(2*Pi/RotateSteps*Angle)-X1L*Sin(2*Pi/RotateSteps*Angle)) );π  X2RN := Round(π(X2R*Cos(2*Pi/RotateSteps*Angle)+Y2R*Sin(2*Pi/RotateSteps*Angle)) );π  Y2RN := Round(π(Y2R*Cos(2*Pi/RotateSteps*Angle)-X2R*Sin(2*Pi/RotateSteps*Angle)) );π  X2LN := Round(π(X2L*Cos(2*Pi/RotateSteps*Angle)+Y2L*Sin(2*Pi/RotateSteps*Angle)) );π  Y2LN := Round(π(Y2L*Cos(2*Pi/RotateSteps*Angle)-X2L*Sin(2*Pi/RotateSteps*Angle)) );ππ  XL := X+X1LN;π  YL := Y+Y1LN;ππ  BuildLine( Border, XL,YL, X+X2LN,Y+Y2LN, Size.X );π  BuildLine( LineBuf, 0, 0, X1RN-X1LN, Y1RN-Y1LN, Size.Y );ππ{π  The only thing that can be optimized is the loop below. I think it shouldπ  be completely in asm.π}π  for I := 1 to Size.X doπ  beginπ   DrawPicLine( PBuffer(@Screen)^[CurPage*VPageLen+(I-1) shr 1],π   (I-1) {mod 2} and 1, XL, YL, Size.Y, LineBuf );π{π    Inc( XL, Border[I].X );π    Inc( YL, Border[I].Y );π}π  asmπ    mov   di,Iπ    shl   di,2π    mov   ax,word ptr border[di]-4π    add   XL,axπ    mov   ax,word ptr Border[di]-4+2π    add   YL,axπ  end;π  end;πend;ππprocedure TRotateApp.Run;πvarπ  C:  Char;πbeginπ  repeatπ    if KeyPressed thenπ    beginπ      C := ReadKey;π      if C = #0 then C := ReadKey;π      case C ofπ #72: Move(0,-10);π #80: Move(0,-10);π #75: Move(-10,0);π #77: Move(10,0);π #81: Rotate(1);π #79: Rotate(-1);π '+': Scale(1+ScaleStep);π '-': Scale(1-ScaleStep);π #27: Exit;π      end;π    end;π   Draw;π{ You can comment out the line below and do all transformation yourself }π   Update;π   FlipPage;π   Inc( FramesNumber );π  until False;πend;ππdestructor TRotateApp.Done;πbeginπ  inherited Done;π  WriteLn( 'Frames per second = ',π    (FramesNumber / ((Time-StartTime)*0.055) ):5:2 );πend;ππvarπ  RotateApp: TRotateApp;πbeginπ  if not RotateApp.Init then Exit;π  RotateApp.Run;π  RotateApp.Done;πend.ππ{---------------------   UNIT CODE NEEDED HERE -------------------- }ππ{π  VGA graphics unit.π  Coded by Mike Shirobokov(MSH) aka Mad Max / Queue members.ππ  This this the very small part of my gfx unit. I leave only functions usedπ  by RotateApp.ππ  Bugs corrected by Alex Grischenkoπ}ππunit VGAGraph;ππinterfaceππuses Objects, Memory;ππconstπ  HRes  = 360;π  VRes  = 320;π  VPageLen = HRes*VRes div 4;ππ{  HRes = 320; VRes=200; Vpagelen=0;}ππtypeπ  PBuffer = ^TBuffer;π  TBuffer = array[ 0..65534 ] of Byte;π  PScreenBuffer = ^TScreenBuffer;π  TScreenBuffer = array[ 0..199, 0..319 ] of Byte;π  TRGBPalette = array[ 0..255 ] of record R,G,B: Byte; end;ππ  PImage = ^TImage;π  TImage = object( TObject )π    Size: TPoint;π    Palette: TRGBPalette;π    Data: PBuffer;π    constructor Load( Name: String );π{   This procedures are now killed. If you need them just write me or seeπ    old mail from me.π    procedure Show( Origin: TPoint; var Buffer );π    procedure ShowRect( Origin: TPoint; NewSize: TPoint; var Buffer ); }π    destructor Done; virtual;π  end;ππ  PGraphApplication = ^TGraphApplication;π  TGraphApplication = object( TObject )π    constructor Init( ModeX : Boolean );π    procedure Run; virtual;π    destructor Done; virtual;π  end;ππvarπ  Screen: TScreenBuffer absolute $A000:0;ππ  procedure SetPalette( var Pal: TRGBPalette );π  procedure Set360x240Mode;π  procedure ShowPage( Page: Integer );ππimplementationππuses PCX;ππconstructor TImage.Load( Name: String );πvarπ  S: TDosStream;π  I: Integer;π  P: OldPCXPicture;π  Len: Word;πbeginπ  inherited Init;π  P.Init( Name );π  if P.Status <> pcxOK thenπ  beginπ    P.Done;π    Fail;π  end;π  Size.X := P.H.XMax - P.H.XMin + 1;π  Size.Y := P.H.YMax - P.H.YMin + 1;π{π  I use DOS memory allocation 'cuz GetMem can't allocate 64Kπ  Even thru DPMI.  :-(π  GetMem( Data, Word(Size.X) * Size.Y );π}π  Len := Word((LongInt(Size.X)*Size.Y+15) div 16);π  LEN:=65536 DIV 16;π  asmπ    mov ah,48hπ    mov bx,Lenπ    int 21hπ    jnc @mem_okπ    xor ax,axπ@mem_ok:π    mov word ptr es:[di].Data+2,axπ    xor ax,axπ    mov word ptr es:[di].Data,axπ  end;ππ  if Data = nil thenπ  beginπ    P.Done;π    Fail;π  end;ππ  fillchar(Data^,len*16-1,0);ππ  Move( P.Pal, Palette, SizeOf(Palette) );π  for I := 0 to 255 doπ  beginπ    Palette[I].R := Palette[I].R shr 2;π    Palette[I].G := Palette[I].G shr 2;π    Palette[I].B := Palette[I].B shr 2;π  end;ππ  for I := 0 to Size.Y-1 doπ    P.ReadLine( Data^[ Word(Size.X)*I ] );π  P.Done;πend;ππdestructor TImage.Done;πbeginπ{π  FreeMem( Data, Word(Size.X)*Size.Y );π}π  asmπ    mov ah,49hπ    mov ax,word ptr es:[di].Data+2π    mov es,axπ    int 21hπ  end;π  inherited Done;πend;ππconstructor TGraphApplication.Init( ModeX : Boolean );πbeginπ  Set360x240Modeπend;ππprocedure TGraphApplication.Run;πbeginπ  Abstract;πend;ππdestructor TGraphApplication.Done;πbeginπ  asmπ    mov ax,3hπ    int 10hπ  end;πend;ππprocedure SetPalette( var Pal: TRGBPalette );πvarπ  I : Integer;πbeginπ  for I := 0 to 255 doπ  beginπ    Port[$3C8] := I;π    Port[$3C9] := Pal[I].R;π    Port[$3C9] := Pal[I].G;π    Port[$3C9] := Pal[I].B;π  end;πend;ππ{  Modified from public-domain mode set code by John Bridges. }ππconstπ SC_INDEX  = $03c4;   {Sequence Controller Index}π CRTC_INDEX = $03d4;   {CRT Controller Index}π MISC_OUTPUT  = $03c2;   {Miscellaneous Output register}ππ{ Index/data pairs for CRT Controller registers that differ betweenπ  mode 13h and mode X. }ππCRT_PARM_LENGTH = 17;πCRTParms : array [1..CRT_PARM_LENGTH] of Word = (ππ $6B00,  { Horz total }π $5901,  { Horz Displayed }π $5A02,  { Start Horz Blanking }π $8E03,  { End Horz Blanking }π $5E04,  { Start H Sync }π $8A05,  { End H Sync }π $0d06,  {vertical total}π $3e07,  {overflow (bit 8 of vertical counts)}π $ea10,  {v sync start}π $8c11,  {v sync end and protect cr0-cr7}π $df12,  {vertical displayed}π $e715,  {v blank start}π $0616,  {v blank end}π $4209,  {cell height (2 to double-scan)}π $0014,  {turn off dword mode}π $e317,  {turn on byte mode}π $2D13 {90 bytes per line}π);ππprocedure Set360x240Mode;πbeginπ asmπ mov     ax,13h  {let the BIOS set standard 256-color}π int     10h     {mode (320x200 linear)}ππ mov     dx,SC_INDEXπ mov     ax,0604hπ out     dx,ax   {disable chain4 mode}π mov     ax,0100hπ out     dx,ax   {synchronous reset while switching clocks}ππ mov     dx,MISC_OUTPUTπ mov     al,0E7hπ out     dx,al   {select 28 MHz dot clock & 60 Hz scanning rate}ππ mov     dx,SC_INDEXπ mov     ax,0300hπ out     dx,ax   {undo reset (restart sequencer)}ππ mov     dx,CRTC_INDEX {reprogram the CRT Controller}π mov     al,11h  {VSync End reg contains register write}π out     dx,al   {protect bit}π inc     dx      {CRT Controller Data register}π in      al,dx   {get current VSync End register setting}π and     al,7fh  {remove write protect on various}π out     dx,al   {CRTC registers}π dec     dx      {CRT Controller Index}π cldπ mov     si,offset CRTParms {point to CRT parameter table}π mov     cx,CRT_PARM_LENGTH {# of table entries}π@SetCRTParmsLoop:π lodsw           {get the next CRT Index/Data pair}π out     dx,ax   {set the next CRT Index/Data pair}π push cxπ mov cx,1000π@loop: loop @loopπ pop cxπ loop    @SetCRTParmsLoopππ mov     dx,SC_INDEXπ mov     ax,0f02hπ out     dx,ax   {enable writes to all four planes}π mov     ax,$A000{now clear all display memory, 8 pixels}π mov     es,ax         {at a time}π sub     di,di   {point ES:DI to display memory}π sub     ax,ax   {clear to zero-value pixels}π mov     cx,VRes*HRes/4/2 {# of words in display memory}π rep     stosw   {clear all of display memory}π end;πend;ππprocedure ShowPage( Page: Integer );πbeginπ  asmπ      mov ax,VPageLenπ      mul word ptr Pageπ      mov bx,axππ      mov dx,3d4hπ      mov al,0chπ      mov ah,bhπ      out dx,axπ      mov dx,3d4hπ      mov al,0dhπ      mov ah,blπ      out dx,axπ{ Uncomment this waiting for retrace if you see flickering }π{π      mov dx,3dahπ @@1: in al,dxπ      test al,00001000bπ      jz @@1π @@2: in   al,dxπ      test al,00001000bπ      jnz  @@2π}π  end;πend;ππEnd.ππ{ --------------------------  UNIT CODE NEEDED HERE -------------}ππ{π  256 color PCX bitmaps handling unit.π  NewPCXPicture object are removed to reduce traffic. If youπ  need it just contact me or dig in old mail from me.π  Coded by Mike Shirobokov(MSH) aka Mad Max / Queue Members.π  Free sourceware.π}ππunit PCX;ππinterfaceππuses Objects;ππtypeπ  TRGBPalette = array[ 0..255 ] of record R,G,B: Byte; end;ππ  PCXHeader = recordπ    Creator,π    Version,π    Encoding,π    Bits: Byte;π    XMin,π    YMin,π    XMax,π    YMax,π    HRes,π    VRes: Integer;π    Palette: array [ 1..48 ] of Byte;π    VMode,π    Planes: Byte;π    BytesPerLine,π    PaletteInfo,π    SHRes,π    SVRes: Word;π    Dummy: array [0..53] of Byte;π  end;ππconstπ  pcxOK   = 0;π  pcxInvalidType = 1;π  pcxNoFile  = 2;ππtypeπ  OldPCXPicture = objectπ    H:  PCXHeader;π    S:  TBufStream;π    Pal: TRGBPalette;π    Status: Integer;π    constructor Init( AFileName: String );π    procedure ReadLine( var Buffer );π    function ErrorText: String;π    destructor Done;π  end;π{π  NewPCXPicture = objectπ    H:  PCXHeader;π    S:  TBufStream;π    Pal: TRGBPalette;π    constructor Init( AFileName: String; HSize: Integer );π    procedure WriteLine( var Buffer );π    destructor Done;π  end;π}πimplementationππtypeπ  GetByteFunc = function: Byte;π  ByteArr = array [0..65534] of Byte;π  PByte  = ^ByteArr;ππprocedure UnpackString( GetByte: GetByteFunc; var Dest; Size: Integer );πvarπ  DestPtr: PByte;π  Count: Integer;π  B:  Byte;π  I:  Integer;πbeginπ  DestPtr := @Dest;π  Count := 0;π  while Count < Size doπ  beginπ    B := GetByte;π    if B < $C0 thenπ    beginπ      DestPtr^[Count] := B;π      Inc(Count);π    endπ    elseπ    beginπ      DestPtr^[Count] := GetByte;π      for I := 0 to B-$C1 doπ DestPtr^[Count+I] := DestPtr^[Count];π      Inc( Count, I+1 );π    end;π  end;πend;ππconstructor OldPCXPicture.Init( AFileName: String );πbeginπ  S.Init( AFileName, stOpenRead, 2048 );π  if S.Status <> stOk thenπ  beginπ    Status := pcxNoFile;π    Exit;π  end;π  S.Read( H, SizeOf(H) );π  if (H.Planes <> 1) or (H.Encoding <> 1) or (H.Bits <> 8 ) thenπ  beginπ    Status := pcxInvalidType;π    Exit;π  end;π  S.Seek( S.GetSize - SizeOf(Pal) );π  S.Read( Pal, SizeOf(Pal) );π  S.Seek( SizeOf(H) );π  Status := pcxOK;πend;ππvarπ  __GetS__: PStream;ππfunction Get: Byte; far;πvarπ  B: Byte;πbeginπ  __GetS__^.Read( B, 1 );π  Get := B;πend;ππprocedure OldPCXPicture.ReadLine( var Buffer );πbeginπ  __GetS__ := @S;π  UnpackString( Get, Buffer, H.BytesPerLine );πend;ππfunction OldPCXPicture.ErrorText: String;πbeginπ  case Status ofπ    pcxOK:π      ErrorText := 'No errors';π    pcxNoFile:π      ErrorText := 'Can''t open file';π    pcxInvalidType:π      ErrorText := 'Only 8 bit PCXs are supported';π  end;πend;ππdestructor OldPCXPicture.Done;πbeginπ  S.Done;πend;ππend.ππ                                                             17     08-24-9413:50ALL                      JENS LARSSON             Grabbing Pixel Color     SWAG9408    )D█    6      ╓   {π GK> I have a slight problem.  I have written a program that runs inπ GK> graphics mode ($13).  I use the following routine to get whatπ GK> colour is at that pixel :-π GK>     PixelColor := MEM[$A000:X + (Y*320)];π GK> This works fine, but it is rather slow.  I was wondering ifπ GK> anybody knew how to do this faster?π}ππ   Function PixColor(x, y : Word) : Byte; Assembler;π    Asmπ     push  dsπ     mov   ax,0a000hπ     mov   ds,axπ     mov   ax,yπ     shl   ax,6π     mov   si,axπ     shl   ax,2π     add   si,axπ     add   si,xπ     lodsbπ     pop   dsπ    End;π                                                                     18     08-24-9413:50ALL                      MARCIN BORKOWSKI         Landscape                SWAG9408    ¿ù┬    30     ╓   πuses crt;ππtype lrgarr = array[0..65534]of byte;ππconstπ pal : array[1..384]of byte =π (0,0,0,48,48,48,1,0,43,1,3,43,2,5,44,2,7,44,3,9,45,4,11,46,5,13,47,6,15,48,π  7,17,49,8,19,50,9,21,51,10,22,52,11,24,52,12,26,54,13,28,54,14,30,56,15,32,π  56,16,34,58,17,34,58,17,36,58,18,38,60,19,40,60,20,42,62,21,44,62,10,31,0,π  11,31,0,11,31,1,11,32,1,12,32,1,12,32,2,12,33,2,13,33,2,14,33,3,15,33,3,15,π  34,3,15,34,4,15,35,4,16,35,4,16,35,5,16,36,5,17,36,5,17,36,6,18,37,6,18,38,π  7,19,38,8,20,39,8,20,40,9,21,40,10,22,41,10,22,42,11,23,42,12,24,43,12,24,π  44,13,25,44,14,25,45,14,26,46,15,27,46,16,27,47,17,28,47,18,28,48,19,29,49,π  19,30,49,20,30,50,21,31,51,21,32,51,22,32,52,23,33,53,23,34,53,24,34,54,25,π  35,55,25,36,55,26,36,56,27,37,57,27,38,57,27,39,57,27,41,57,27,42,57,27,43,π  57,27,44,57,27,45,57,27,46,57,27,47,57,27,49,57,27,50,57,27,51,57,27,52,57,π  27,53,57,27,55,57,27,56,57,27,57,57,27,58,57,27,58,57,26,58,57,25,58,57,24,π  58,56,23,58,55,22,58,54,20,58,53,19,58,51,18,58,50,17,58,50,16,58,49,15,58,π  48,14,58,47,13,58,46,12,58,45,11,58,44,11,58,44,10,58,43,10,58,42,9,57,41,π  8,57,40,8,56,39,7,56,38,6,55,37,5,55,35,4,54,33,4,54,31,2,32,32,32,63,63,63,π  63,63,63,63,63,63,63,63,63,48,48,48,63,63,63,63,63,63);ππvarπ mp,scr : ^lrgarr;π rng : array[0..320]of byte;π dir,i,x,y : integer;ππfunction ncol(mc,n,dvd : integer): integer;πvar loc : integer;πbeginπ loc:=(mc+n-random(2*n)) div dvd; ncol:=loc;π if loc>250 then ncol:=250; if loc<5 then ncol:=5πend;ππprocedure plasma(x1,y1,x2,y2 : word);πvar xn,yn,dxy,p1,p2,p3,p4 : word;πbeginπ if (x2-x1<2) and (y2-y1<2) then EXIT;π p1:=mp^[256*y1+x1]; p2:=mp^[256*y2+x1]; p3:=mp^[256*y1+x2];π p4:=mp^[256*y2+x2]; xn:=(x2+x1) shr 1; yn:=(y2+y1) shr 1;π dxy:=5*(x2-x1+y2-y1) div 3;π if mp^[256*y1+xn]=0 then mp^[256*y1+xn]:=ncol(p1+p3,dxy,2);π if mp^[256*yn+x1]=0 then mp^[256*yn+x1]:=ncol(p1+p2,dxy,2);π if mp^[256*yn+x2]=0 then mp^[256*yn+x2]:=ncol(p3+p4,dxy,2);π if mp^[256*y2+xn]=0 then mp^[256*y2+xn]:=ncol(p2+p4,dxy,2);π mp^[256*yn+xn]:=ncol(p1+p2+p3+p4,dxy,4);π plasma(x1,y1,xn,yn); plasma(xn,y1,x2,yn);π plasma(x1,yn,xn,y2); plasma(xn,yn,x2,y2);πend;ππprocedure draw(xp,yp,dir : integer);πvar z,zobs,ix,iy,iy1,iyp,ixp,x,y,s,csf,snf,mpc,i,j : integer;πbeginπ fillchar(rng,sizeof(rng),200);  zobs:=100+mp^[256*yp+xp];π csf:=round(256*cos(dir/180*pi)); snf:=round(256*sin(dir/180*pi));π fillchar(scr^,64000,0);π for iy:=yp to yp+55 doπ beginπ  iy1:=1+2*(iy-yp); s:=4+300 div iy1;π  for ix:=xp+yp-iy to xp-yp+iy doπ  beginπ   ixp:=xp+((ix-xp)*csf+(iy-yp)*snf) div 256;π   iyp:=yp+((iy-yp)*csf-(ix-xp)*snf) div 256;π   x:=160+360*(ix-xp) div iy1;π   if (x>=0) and (x+s<=318) thenπ   beginπ    z:=mp^[256*iyp+ixp]; mpc:=z shr 1;π    if z<47 then z:=46;  y:=100+(zobs-z)*30 div iy1;π    if (y<=199) and (y>=0) thenπ     for j:=x to x+s doπ     beginπ      for i:=y to rng[j] do scr^[320*i+j]:=mpc;π      if y<rng[j] then rng[j]:=yπ     end;π   end;π  end;π end;π move(scr^,mem[$A000:0],64000);πend;ππbeginπ writeln('Use arrow keys to pan in/out left/right ... any key to continue ..');π readkey;π randomize; x:=0; y:=0; dir:=0; new(mp); fillchar(mp^,65535,0);π new(scr); mp^[$0000]:=128; plasma(0,0,256,256);π asm xor ax,ax; mov al,$13; int $10; end;π port[$3C8]:=0; for i:=1 to 384 do port[$3C9]:=pal[i];π repeatπ  dir:=dir mod 360; draw(x,y,dir);π  case readkey ofπ   #0 : case readkey ofπ     #75 : dec(dir,10);π     #77 : inc(dir,10);π     #72 : begin y:=y+round(4*cos(dir/180*pi));π           x:=x+round(4*sin(dir/180*pi)); end;π     #80 : begin y:=y-round(4*cos(dir/180*pi));π           x:=x-round(4*sin(dir/180*pi)); end;π       end;π   #27 : begin asm xor ax,ax; mov al,$3; int $10; end; HALT endπ  endπ until false;πend.π                 19     08-24-9413:50ALL                      JONAS MALMSTEN           plasma                   SWAG9408    Um.    22     ╓   {πYesterday I saw Bas' plasma routine. Real nice! But... a little slow I thoughtπso I improved it. Another thing, Bas, the bouble buffer didn't work on myπet4000, the bplptr never changed in your mode.ππWell, enjoy this new routine!π}ππprogram plasma;ππ{ bigscreenplasma, by Bas van Gaalen & Sven van Heel, Holland, PD   }π{ Improved by GEM, Sweden (convertion to asm --> many times faster) }ππusesπ  crt;ππconstπ  vidseg:word=$a000;ππvarπ  stab1,stab2:array[0..255+80] of byte;π  x:word;ππprocedure setpal(c,r,g,b:byte); assembler;πasmπ   mov dx,3c8hπ   mov al,[c]π   out dx,alπ   inc dxπ   mov al,[r]π   out dx,alπ   mov al,[g]π   out dx,alπ   mov al,[b]π   out dx,alπend;ππbeginπ  asmπ     mov ax,0013hπ     int 10hπ     mov dx,03c4hπ     mov ax,0604hπ     out dx,axπ     mov dx,03d4hπ     mov ax,4609hπ     out dx,axπ     mov ax,0014hπ     out dx,axπ     mov ax,0e317hπ     out dx,axπ     mov es,vidsegπ     xor di,diπ     xor ax,axπ     mov cx,16000π     rep stoswπ  end;π  for x:=0 to 63 do beginπ    setpal(x,x div 4,x div 2,x);π    setpal(127-x,x div 4,x div 2,x);π    setpal(127+x,20+x div 4,x div 2,x);π    setpal(254-x,20+x div 4,x div 2,x);π  end;π  for x:=0 to 255+80 do beginπ    stab1[x]:=round(sin(2*pi*x/255)*128)+128;π    stab2[x]:=round(cos(2*pi*x/255)*128)+128;π  end;π  asmπ     mov cl,50π     mov ch,90π     mov es,vidsegπ     push bpπ   @main:ππ{     mov dx,3c8h    (* For checking rastertime *)π     xor al,alπ     out dx,alπ     inc dxπ     out dx,alπ     out dx,alπ     out dx,al}ππ     mov dx,3dahπ   @vert1:π     in al,dxπ     test al,8π     jz @vert1π   @vert2:π     in al,dxπ     test al,8π     jnz @vert2ππ     mov dx,3dah    (* This is kinda rediculous! *)π   @vert1b:         (* I have to insert another vbl to slow it down.... *)π     in al,dxπ     test al,8π     jz @vert1bπ   @vert2b:π     in al,dxπ     test al,8π     jnz @vert2bππ{     mov dx,3c8h    (* For checking rastertime *)π     xor al,alπ     out dx,alπ     mov al,30π     inc dxπ     out dx,alπ     out dx,alπ     out dx,al}ππ     inc clπ     inc chπ     xor di,diπ     mov bp,diπ   @loooooop:π     mov si,offset stab1π     mov bx,bpπ     add bl,clπ     mov dl,[si+bx]π     xor dh,dhπ     mov bl,chπ     mov al,[si+bx]π     add si,dxπ     mov bx,bpπ     add bl,alπ     mov bl,[bx+offset stab2]π     mov bh,blπ     mov dx,40π   @again:π     lodswπ     add ax,bxπ     stoswπ     dec dxπ     jnz @againπ     cmp si,offset stab1[256]π     jb @1π     sub si,256π   @1:π     inc bpπ     cmp bp,58π     jne @loooooopπ     in al,60hπ     cmp al,1π     jne @mainπ     pop bpπ  end;π  textmode(lastmode);πend.ππ                                                                                          20     08-24-9413:50ALL                      OLAF BARTELT             VGA 640X480x16           SWAG9408    G%¿φ    11     ╓   {π NV>     Could somebody tell me how to use mode 640x480x16? Iπ NV> don't mean using     it with int 10, 'cause it's too slow,π NV> but writing directly to VGA     memory. So how do I draw aπ NV> pixel and how do I read a pixel?πwell, you set the mode with:ππ      ASM MOV AX, 12h; INT 10h; END;ππand then draw a pixel with: }ππPROCEDURE plot_640x480x16(x, y : WORD; c : BYTE); ASSEMBLER;πASMπ  {$IFDEF DPMI}π  MOV ES, SEGA000π  {$ELSE}π  MOV AX, $A000π  MOV ES, AXπ  {$ENDIF}π  MOV DI, xπ  MOV CX, DIπ  SHR DI, 3π  MOV AX, 80π  MUL yπ  ADD DI, AXπ  AND CL, $07π  MOV AH, $80π  SHR AH, CLπ  MOV AL, $08π  MOV DX, $03CEπ  OUT DX, AXπ  MOV AL, cπ  MOV AH, [ES:DI]π  MOV [ES:DI], ALπEND;πππ{ and read a pixel with: }πππFUNCTION point_640x480x16(x, y : WORD) : BYTE; ASSEMBLER;πASMπ  MOV  AX, 80π  MUL  yπ  MOV  SI, xπ  MOV  CX, SIπ  SHR  SI, 3π  ADD  SI, AXπ  AND  CL, $07π  XOR  CL, $07π  MOV  CH, 1π  SHL  CH, CLπ  {$IFDEF DPMI}π  MOV  ES, SEGA000π  {$ELSE}π  MOV  AX, $A000π  MOV  ES, AXπ  {$ENDIF}π  MOV  DX, $03CEπ  MOV  AX, 772π  XOR  BL, BLπ@gp1:π  OUT  DX, AXπ  MOV  BH, ES:[SI]π  AND  BH, CHπ  NEG  BHπ  ROL  BX, $0001π  DEC  AHπ  JGE  @gp1π  MOV  AL, BLπEND;ππ                                                                                                                21     08-24-9413:51ALL                      LUIS MEZQUITA            Moving Poligon           SWAG9408    åMká    76     ╓   {πPS> I see that a lot of people around here have polygon, texture mapping andπPS> 3D routines so why don't you all post them here, even if you alreadyπPS> have done in the past cause there are people who didn't get themπPS> and want them :)π}ππ{$G+,R-}πProgram Polygoned_and_shaded_objects;ππ{ Mode-x version of polygoned objects          }π{ Originally by Bas van Gaalen & Sven van Heel }π{ Optimized by Luis Mezquita Raya              }ππuses Crt,x3Dunit2;π         { ^^^^^  Contained in GRAPHICS.SWG file }π{$DEFINE Object1}                       { Try an object between 1..4 }ππconstππ{$IFDEF Object1}                        { Octagon }π nofpolys=9;                            { Number of poligons-1 }ππ nofpoints=11;                          { Number of points-1 }ππ polypoints=4;                          { Number of points for each poly }ππ sc=5;                                  { Number of visible planes }ππ cr=23;                                 { RGB components }π cg=8;π cb=3;ππ point:array[0..nofpoints,0..2] of integer=(π    (-20,-20, 30),( 20,-20, 30),( 40,-40,  0),( 20,-20,-30),π    (-20,-20,-30),(-40,-40,  0),(-20, 20, 30),( 20, 20, 30),π    ( 40, 40,  0),( 20, 20,-30),(-20, 20,-30),(-40, 40,  0));ππ planes:array[0..nofpolys,0..3] of byte=(π    (0,1,7,6),(1,2,8,7),(9,8,2,3),(10,9,3,4),(10,4,5,11),π    (6,11,5,0),(0,1,2,5),(5,2,3,4),(6,7,8,11),(11,8,9,10));π{$ENDIF}ππ{$IFDEF Object2}                        { Cube }π nofpolys=5;                            { Number of poligons-1 }ππ nofpoints=7;                           { Number of points-1 }ππ polypoints=4;                          { Number of points for each poly }ππ sc=3;                                  { Number of visible planes }ππ cr=0;                                  { RGB components }π cg=13;π cb=23;ππ point:array[0..nofpoints,0..2] of integer=(π    (-40,-40, 40),( 40,-40, 40),( 40,-40,-40),(-40,-40,-40),π    (-40, 40, 40),( 40, 40, 40),( 40, 40,-40),(-40, 40,-40));ππ planes:array[0..nofpolys,0..3] of byte=(π    (0,1,5,4),(1,5,6,2),(6,7,3,2),π    (7,3,0,4),(0,1,2,3),(6,5,4,7));π{$ENDIF}ππ{$IFDEF Object3}                        { Octahedron }π nofpolys=7;                            { Number of poligons-1 }ππ nofpoints=5;                           { Number of points-1 }ππ polypoints=3;                          { Number of points for each poly }ππ sc=4;                                  { Number of visible planes }ππ cr=0;                                  { RGB components }π cg=3;π cb=23;ππ point:array[0..nofpoints,0..2] of integer=(π    (  0, 0,  45),(-40,-40,  0),(-40, 40,  0),( 40, 40,  0),π    ( 40,-40,  0),(  0,  0,-45));ππ planes:array[0..nofpolys,0..3] of byte=(π    (0,1,2,0),(0,2,3,0),(0,3,4,0),(0,4,1,0),π    (5,1,2,5),(5,2,3,5),(5,3,4,5),(5,4,1,5));ππ{$ENDIF}ππ{$IFDEF Object4}                        { Spiky }π nofpolys=15;                           { Number of poligons-1 }ππ nofpoints=19;                          { Number of points-1 }ππ polypoints=4;                          { Number of points for each poly }ππ sc=5;                                  { Number of visible planes }ππ cr=23;                                 { RGB components }π cg=5;π cb=5;ππ point:array[0..nofpoints,0..2] of integer=(π    (-10,-10, 30),( 10,-10, 30),( 30,-30,  0),( 10,-10,-30),π    (-10,-10,-30),(-30,-30,  0),(-10, 10, 30),( 10, 10, 30),π    ( 30, 30,  0),( 10, 10,-30),(-10, 10,-30),(-30, 30,  0),π    ( -2, -2, 60),( -2,  2, 60),(  2, -2, 60),(  2,  2, 60),π    ( -2, -2,-60),( -2,  2,-60),(  2, -2,-60),(  2,  2,-60));ππ planes:array[0..nofpolys,0..3] of byte=(π    (0,1,14,12),(7,15,13,6),(1,14,15,7),(6,13,12,0),π    (1,2,8,7),(9,8,2,3),π    (10,9,19,17),(10,4,16,17),(3,4,16,18),(3,9,19,18),π    (10,4,5,11),π    (6,11,5,0),(0,1,2,5),(5,2,3,4),(6,7,8,11),(11,8,9,10));π{$ENDIF}ππtype  polytype=array[0..nofpolys] of integer;π      pointype=array[0..nofpoints] of integer;ππ      ptnode=word;π      stack=ptnode;ππconst soplt=SizeOf(polytype);π      sopit=SizeOf(pointype);π      xst:integer=1;π      yst:integer=1;π      zst:integer=-2;ππvar   polyz,pind:array[byte] of polytype;π      xp,yp:array[byte] of pointype;π      phix:byte;ππProcedure QuickSort(lo,hi:integer); assembler; { Iterative QuickSort }πvar i,j,x,y:integer;                           { NON RECURSIVE }πasmπ        mov ah,48h                      { Init stack }π        mov bx,1π        int 21hπ        jc @exitπ        mov es,axπ        xor ax,axπ        mov es:[4],axππ        mov cx,lo                       { Push(lo,hi) }π        mov dx,hiπ        call @Pushππ@QS:    mov ax,es:[4]                   { ¿Stack empty? }π        and ax,axπ        jz @Emptyππ        mov cx,es:[0]                   { Top(lo,hi) }π        mov dx,es:[2]π        mov lo,cxπ        mov hi,dxππ        mov bx,es:[4]                   { Pop }π        mov ah,49hπ        int 21hπ        jc @exitπ        mov es,bxππ        mov ax,cx                       { ax:=(i+j) div 2 }π        mov bx,dxπ        add ax,bxπ        shr ax,1ππ        lea bx,polyz                    { ax:=polyz[ax] }π        call @indexπ        mov x,axππ@Rep:   mov ax,cx                       { repeat ... }π        lea bx,polyz                    { while polyz[i]<x do ... }π        call @indexπ        cmp ax,xπ        jge @Rep2π        inc cx                          { inc(i); }π        jmp @Repππ@Rep2:  mov ax,dx                       { while x<polyz[j] do ... }π        call @indexπ        cmp x,axπ        jge @EndRπ        dec dx                          { dec(j); }π        jmp @Rep2ππ@EndR:  cmp cx,dx                       { if i>j ==> @NSwap}π        jg @NBlππ        je @NSwapπ        push cxππ        mov ax,cxπ        call @indexπ        mov cx,ax                       { cx:=polyz[i] }π        mov si,diππ        mov ax,dx                       { polyz[i]:=polyz[j] }π        call @indexπ        mov [si],axππ        mov [di],cx                     { polyz[j]:=cx }π        pop axππ        push axπ        lea bx,pindπ        call @indexπ        mov cx,ax                       { cx:=pind[i] }π        mov si,diππ        mov ax,dx                       { pind[i]:=pind[j] }π        call @indexπ        mov [si],axππ        mov [di],cx                     { pind[j]:=cx }ππ        pop cxπ@NSwap: inc cxπ        dec dxππ@NBl:   cmp cx,dx                       { ... until i>j; }π        jle @Repππ        mov i,cxπ        mov j,dxππ        mov dx,hi                       { if i>=hi ==> @ChkLo }π        cmp cx,dxπ        jge @ChkLoππ        call @Push                      { Push(i,hi) }ππ@ChkLo: mov cx,lo                       { if lo>=j ==> @QSend }π        mov dx,jπ        cmp cx,dxπ        jge @QSendππ        call @Push                      { Push(lo,j) }ππ@QSend: jmp @QS                         { loop while stack isn't empty }ππ@Empty: mov ah,49hπ        int 21hπ        jmp @exitππ@index: shl ax,1                        { ax:=2*ax }π        add ax,bxπ        mov di,axπ        push bxπ        mov bl,sopltπ        mov al,phixπ        xor ah,ahπ        mul blπ        add di,ax                       { di=2*index+SizeOf(polytype)+polyz }π        pop bxπ        mov ax,[di]π        retππ@Push:  mov ah,48h                      { Push into stack }π        mov bx,1π        int 21hπ        jc @exitπ        mov bx,esπ        mov es,axπ        mov es:[0],cxπ        mov es:[2],dxπ        mov es:[4],bxπ        mov di,axπ        retππ@exit:πend;ππProcedure Calc;πvar z:pointype;π    spx,spy,spz,π    cpx,cpy,cpz,π    zd,x,y,i,j,k:integer;π    n,key,phiy,phiz:byte;πbeginπ phix:=0;π phiy:=0;π phiz:=0;π FillChar(xp,sizeof(xp),0);π FillChar(yp,sizeof(yp),0);ππ repeatππ  spx:=sinus(phix);                     { 'Precookied' constanst }π  spy:=sinus(phiy);π  spz:=sinus(phiz);ππ  cpx:=cosinus(phix);π  cpy:=cosinus(phiy);π  cpz:=cosinus(phiz);ππ  for n:=0 to nofpoints doπ   beginπ    i:=(cpy*point[n,0]-spy*point[n,2]) div divd;π    j:=(cpz*point[n,1]-spz*i) div divd;π    k:=(cpy*point[n,2]+spy*point[n,0]) div divd;π    x:=(cpz*i+spz*point[n,1]) div divd;π    y:=(cpx*j+spx*k) div divd;π    z[n]:=(cpx*k-spx*j) div divd;π    zd:=z[n]-dist;π    xp[phix,n]:=(160+cpx)-(x*dist) div zd;π    yp[phix,n]:=(200+spz) div 2-(y*dist) div zd;π   end;ππ  for n:=0 to nofpolys doπ   beginπ    polyz[phix,n]:=(z[planes[n,0]]+z[planes[n,1]]+π                    z[planes[n,2]]+z[planes[n,3]]) div 4;π    pind[phix,n]:=n;π   end;ππ  QuickSort(0,nofpolys);π  inc(phix,xst);π  inc(phiy,yst);π  inc(phiz,zst);π until phix=0;πend;ππProcedure ShowObject;πvar n:byte; pim:integer;πbeginπ retrace;π if address=0π then address:=16000π else address:=0;π setaddress(address);π cls;π for n:=sc to nofpolys doπ  beginπ   pim:=pind[phix,n];π   polygon(xp[phix,planes[pim,0]],yp[phix,planes[pim,0]],π           xp[phix,planes[pim,1]],yp[phix,planes[pim,1]],π           xp[phix,planes[pim,2]],yp[phix,planes[pim,2]],π           xp[phix,planes[pim,3]],yp[phix,planes[pim,3]],π           polyz[phix,n]+30);π  end;πend;ππProcedure Rotate;πvar i:byte;πbeginπ setmodex;π address:=0;π Triangles:=polypoints=3;π for i:=1 to 80 do setpal(i,cr+i shr 1,cg+i shr 1,cb+i shr 1);π setborder(63);π repeatπ  ShowObject;π  inc(phix,xst);π until KeyPressed;π setborder(0);πend;ππvar i:byte;π    s:stack;π    x,y:integer;ππbeginπ {border:=True;}π if ParamCount=1π then beginπ       Val(ParamStr(1),xst,yst);π       if yst<>0 then Halt;π       zst:=-2*xst;π       yst:=xst;π      end;π WriteLn('Wait a moment ...');π Calc;π Rotate;π TextMode(LastMode);πend.ππ        But ... wait a moment ... you also need x3dUnit2.pasπ        which is also included in the SWAG filesπ                              22     08-24-9413:56ALL                      SIMEON SPRY              SCI File Viewer          SWAG9408    ;{åµ    19     ╓   πProgram ViewASCi;ππ{ Simple SCi Viewer - By Simeon SpryππThis code will display a SCi (320*200*256) file. I would reccomend that youπadd code to find out if the SCi File name is valid. I had some, but I gotπit out of a book so it *might* be copyrighted :-(. You also might want toπsave the old pallete and restore it afterwards I didn't do it because Iπlost my reference.ππThis may be freely distributed, if you incorporate any portions of thisπcode into a part of anything you MUST give me some credit.π}πππProcedure ViewSci( SciF : STRING);π CONST    Header : Array[1..4] OF CHAR = ('R','I','X','3');ππ VAR     SciFile : File;π         HeaderBuf : Array[1..10] OF CHAR;π         NewPal    : Array[1..768] OF BYTE; { 3 Bytes Per colour, 3*256 = 768}π         OldPal    : Array[1..768] OF BYTE; { "  "  "}π         Screen    : Array[1..64000] OF BYTE ABSOLUTE $A000:0000; { Direct toπthe screen }π         i         : integer;π Procedure SetPal(Pallete : Array OF BYTE);π VARπ   PalPtr : POINTER;π BEGINπ  PalPtr := @Pallete;π  asmπ   mov ax,1012hπ   xor bx,bxπ   mov cx,0100hπ   les dx,PalPtrπ   int 10hπ  end;π END;ππ Procedure WaitForKey;assembler;π  ASMπ   xor ax,axπ   int 16hπ  END;πProcedure SetMode(Mode : BYTE); assembler;π  ASMπ    mov ah, 00π    mov al, modeπ    int 10hπ  END;ππ BEGINπ  { Open The File }π  assign(SciFile, SciF);π  Reset(SciFile,1);ππ  { Check The Header }π  BlockRead(SciFile,HeaderBuf,SizeOF(HeaderBuf));π  For i := 1 to 4 DOπ   Beginπ    If HeaderBuf[i] <> Header[i] Thenπ     BEGINπ      WriteLn;π      WriteLn(' Invalid SCI File. ');π      WriteLn;π      Halt(1);π     END;π   End;ππ { Set Mode $13 }π SetMode($13);ππ { Read Pallete into a 768 Byte Buffer & DisPlay. }π  BlockRead(SciFile,NewPal,768);π  SetPal(NewPal);ππ { Read 64000 bytes then write DIRECTLY to Video Memory }π  BlockRead(SCIFile,Screen,64000);π  cLOSE(SCIFILE);π { Wait Until Key Pressed }π WaitForKey;ππ { Set Text Mode }π  SetMode($3);πEND;ππVar SciFile : String[12];ππBEGINπ   { Ask For File To View }π  WriteLn('SCi Viewer - By Simeon Spry');π  Write('View File: ');π  ReadLn(SciFile);ππ   { View SCi File }π  ViewSCI( SciFile );ππ   { Display Made-By Message }π  WriteLn('Simple SCi Viewer by Simeon Spry');π  WriteLn;πEND.π                                                                      23     08-24-9413:56ALL                      BAS VAN GAALEN           Scroll Bars              SWAG9408    Ω╠E▒    36     ╓   USES dos, crt;ππCONSTπ    v_vidseg   : WORD = $B800;  { $B000 for mono }π    v_columns  : BYTE = 80;     { Number of CRT columns }ππVARπ    x : BYTE;π{πthe dspat routine, as you can see.  Displays a string QUICKLYπIf 'Col' (=columns, NOT color) is negative (-1) the centence will be centered.πWorks also in exotic screenmodes, like 132x44, 100x44 or whatever you like.π}πprocedure dspat(Str : string; Col : integer; Row,Attr : byte); assembler;πasmπ  push ds          { Save Turbo's DS }π  mov es,v_vidseg  { Place VideoBuffer in es }π  xor dh,dh        { Clear DH }π  mov dl,v_columns { Bytes per row }ππ  lds si,Str       { DS:SI pts to Str }π  xor cx,cx        { clear CX }π  mov cl,[si]      { String len counted in CX }π  jcxz @l5         { If null, quit }π  inc si           { Point DS:SI to first char }ππ  mov ax,Col       { Get Column value }π  cmp ax,0π  jge @l6          { Absolute, or centered? }ππ  mov ax,dxπ  sub ax,cx        { Substract stringlen from total }π  shr ax,1         { Centre}ππ @l6:π  mov di,axπ  shl di,1         { Double for attributes }ππ  mov al,Row       { Get Row value }π  mul dl           { Times rows }π  shl ax,1ππ  add di,ax        { ES:DI pts to lst pos }π  cld              { Direction flag forward }π  mov ah,Attr      { Get Attribute }π @l1:π  lodsb            { Get a character}π  stosw            { Write it with attribute }π  loop @l1         { Go do next }π @l5:π  pop ds           { Restore DS and quit }πend;ππprocedure filltext(Dir : char; X1,Y1,X2,Y2,Col : byte); assembler;πasmπ  push ds          { Save Turbo's DS }ππ  xor dh,dh        { Clear DH }π  mov dl,v_columns { Bytes per row (number of columns) }ππ  xor ah,ahπ  mov es,v_vidseg  { Place VideoBuffer in ES and DS }π  mov al,[X1]π  mov di,axπ  shl di,1         { Double for attributes }π  mov al,[Y1]      { Get Row value }π  mul dl           { Times rows }π  shl ax,1π  add di,ax        { ES:DI pts to upperleft corner }ππ  xor ch,chπ  mov cl,[X2]π  inc clπ  sub cl,[X1]      { Number of bytes to move in CL (columns) }π  xor bh,bhπ  mov bl,[Y2]π  inc blπ  sub bl,[Y1]      { Number of rows to move in BL }ππ  sub dl,[X2]      { Substract right site }π  dec dlπ  shl dx,1         { Times two for attribs }π  xor ah,ah        { Clear AH }π  mov al,[X1]      { Left site }π  shl ax,1         { Times two for attribs }π  add dx,ax        { Calculated difference between last col - first col }ππ  mov al,[Dir]π  mov ah,[Col]ππ  cld              { Direction flag forward }π @L1:π  push cxπ  rep stoswπ  pop cxπ  add di,dxπ  dec blπ  jnz @L1ππ  pop ds           { Restore DS and quit }πend;ππ{ Displays Veritical scrollbar }πprocedure ScrollBar(BarXPos,π                    BarYPos : byte;π                    CurPos,π                    ScrLen,                     { max screen row }π                    NofItems : word;π                    ColAttr : byte);πvar barpos,maxpos : word;πbeginπ  dspat(#30,barxpos,barypos,colattr);π  dspat(#31,barxpos,barypos+scrlen-1,colattr);π  filltext('▒',barxpos,barypos+1,barxpos,barypos+scrlen-2,colattr);π  if nofitems >= 1 then beginπ    maxpos := scrlen-3;π    if nofitems <> 1 then barpos := round(((curpos-1)/(nofitems-1))*maxpos)π    else barpos := 0;π    dspat('■',barxpos,barypos+barpos+1,colattr);π  end;πend; { ScrollBar }ππBEGIN  { demo coded by Gayle Davis for SWAG 8/18/94 }ππ   ClrScr;π   { put at col 40 of Row x, 3rd item selected }ππ   FOR X := 1 to 24 DOπ       BEGINπ       ScrollBar(40,1,x,22,40,31);π       DELAY(300);π       END;ππEND.ππThe assembler stuff is nicely documented, so shouldn't be a problem. What'sπmissing here, you can define as constants at the top of your source, or try toπfind out using interrupt-calls or whatever...ππBtw: these routines are taken from my very private video-unit, and seem to workπon many different configurations (so far...) But that's also due to the factπthat the v_columns is found through some interrupt-calls and stuff...πThe routines work also in 132x44 or whatever strange video-mode.ππAnother point of discussion: no snow-checking is performed. I got in someπanoying discussions about this, because (imho) CGA's are hardly used theseπdays. So it seems a little ... nuts ... to make support for that hand full ofπCGA-users. Ah well, enclose the sc yourself. it's not hard, but it REALY slow'sπstuff down. And these routines were designed with SPEED as first concern andπcompatibily with MODERN hardware as a second...ππ _    _π|_]  | _π|__].|__].π                     24     08-24-9413:56ALL                      JENS LARSSON             Scrolling Images         SWAG9408    »ƒm    18     ╓   {πMichael, you wondered how you could scroll an image (320*200) over theπscreen. And yes, as you probably have figured out, the most reliableπsolution to that is mode-x (or tweaked mode or whatever...).πHere's an example program:ππ--------------------------------------------------------->8-------------------π{ππ Mode-x scrolling, by Jens Larsson 2:201/2120.3, Sweden, PD.π ( btw, hope you know some assembly... <g> )ππ}π{$G+}πUses Crt;ππ   Var i, ScrBase : Word;ππ    Procedure PutPix(x, y : Word; Color : Byte); Assembler;π      Asmπ        mov     ax,0a000hπ        mov     es,axπ        mov     bx,xπ        mov     dx,3c4hπ        mov     ax,0102hπ        mov     cl,blπ        and     cl,3π        shl     ah,clπ        out     dx,axπ        mov     ax,yπ        shl     ax,4π        mov     di,axπ        shl     ax,2π        add     di,axπ        shr     bx,2π        add     di,bxπ        add     di,ScrBaseπ        mov     al,Colorπ        mov     es:[di],alπ      End;ππ    Procedure ScrPan(ScrOfs : Word); Assembler;π      Asmπ        mov     bx,ScrOfsπ        mov     dx,3d4hπ        mov     ah,bhπ        mov     al,0chπ        out     dx,axπ        mov     ah,blπ        inc     alπ        out     dx,axπ      End;ππ    Procedure SetModeX; Assembler;π      Asmπ        mov     ax,0012hπ        int     10hπ        mov     ax,0013hπ        int     10hπ        mov     dx,3c4hπ        mov     ax,0604hπ        out     dx,axπ        mov     dx,3d4hπ        mov     ax,0014hπ        out     dx,axπ        mov     ax,0e317hπ        out     dx,axπ      End;ππ    Procedure Synk; Assembler;π      Asmπ        mov     dx,3dahπ@L1:π        in      al,dxπ        test    al,08hπ        jne     @L1π@L2:π        in      al,dxπ        test    al,08hπ        je      @L2π      End;ππ       Beginπ         Randomize;π         SetModeX;π         ScrBase := 200*80;π         For i := 0 to 9999 do PutPix(Random(320),Random(200),Random(256));π         For i := 0 to 200 do Beginπ           ScrPan(i*80);π           Synk;π          End;π         ReadKey;π         Asm; mov ax,0003h; int 10h; End;π       End.ππ                                                                    25     08-24-9413:58ALL                      JOHN HOWARD              Sprite Game              SWAG9408    ▀î/{    94     ╓   πprogram SpriteGame;         {Verifies a VGA is present}π{$G+,R-}π(* jh  Syntax:  spritegame.exe  [number]π  optional number is the total population of sprites.  Default is maxsprites.π*)π{ Original Sprites program by Bas van Gaalen, Holland, PD }π{ Modified by Luis Mezquita Raya }π{ Modified by John Howard (jh) into a game }π{ 30-MAY-1994 jh Version 1.0π  Now a game to see which sprite survives the longest.π  Renamed tScrArray to Screen, and tSprArray to SpriteData.π  Removed CRT unit & saved around 1616 bytes.  Added command line parameter.π  Added timer and energy definitions to provide statistics.π  21-JUN-1994 jh Version 1.1 = ~7.5kπ  Added OnlyVGA and SetMode procedures.  Added CharSet & CharType definitions.π  Implemented characters as sprites.π  29-JUN-1994 jh Version 1.2 = ~8.5k due to command line helpπ  Places identification on each sprite by using HexDigits.  CharColor defaultsπ  to sprite number (0..maxsprites) as a color index in the palette.  Fixed bugπ  in moire background screen limits.π}πconstπ      maxsprites=128;                   { Number of sprites is [1..128] }π      pxsize=320;                       { screen x-size }π      pysize=200;                       { screen y-size }π      xsize=32;                         { sprite x-size }π      ysize=32;                         { sprite y-size }π      CharRows=8;                       { Characters are 8 rows high }π      HexDigits : ARRAY[0..15] OF Char = '0123456789ABCDEF';ππtypeπ      Screen=array[0..pysize-1, 0..pxsize-1] of byte;π      pScreen=^Screen;π      SpriteData=array[0..ysize-1, 0..xsize-1] of byte;π      pSpriteData=^SpriteData;π      SprRec=recordπ              x,y : word;              {Absolute location of sprite}π              xspd,yspd : shortint;    {Velocity horizontal and vertical}π              energy : shortint;       {Hide is neg., dead is 0, show is pos.}π              buf : pSpriteData;       {Rectangle of sprite definition}π             end;π      CharType = array[1..CharRows] of Byte;ππvarπ      CharSet : array[0..255] of CharType absolute $F000:$FA6E;π      sprite : array[1..maxsprites] of SprRec;π      vidscr,virscr,bgscr : pScreen;   {video, virtual, background screens}π      dead : byte;                     {Counts the dead sprites}π      survivor : byte;                 {Identify the last dead sprite}π      Population : word;               {Population from 1..128}π      {CharColor : byte;}              {Character digit color 0..255}ππ      Timer : longint;                 {Stopwatch}π      H, M, S, S100 : Word;π      Startclock, Stopclock : Real;π      mins, secs     : integer;π      Code: integer;                     {temporary result of VAL conversion}ππprocedure GetTime(var Hr, Mn, Sec, S100 : word); assembler; {Avoids DOS unit}πasmπ    mov ah,2chπ    int 21hπ    xor ah,ah                 {fast register clearing instead of MOV AH,0}π    mov al,dlπ    les di,S100π    stoswπ    mov al,dhπ    les di,Secπ    stoswπ    mov al,clπ    les di,Mnπ    stoswπ    mov al,chπ    les di,Hrπ    stoswπend;ππprocedure StartTimer;πbeginπ  GetTime(H, M, S, S100);π  StartClock := (H * 3600) + (M * 60) + S + (S100 / 100);πend;ππprocedure StopTimer;πbeginπ  GetTime(H, M, S, S100);π  StopClock := (H * 3600) + (M * 60) + S + (S100 / 100);π  Timer := trunc(StopClock - StartClock);π  secs := Timer mod 60;                             {Seconds remaining}π  mins := Timer div 60;                             {Reduce into minutes}πend;πfunction KeyPressed : boolean; assembler;   {Avoids unit CRT.KeyPressed}πasmπ    mov ah,01h;    int 16h;    jnz @0;    xor ax,ax;    jmp @1;π@0: mov al,1π@1:πend;ππprocedure SetMode(M:byte); assembler;πasmπ    mov ah,0;        mov al,M;        int 10h;πend;πprocedure SetPal(col,r,g,b:byte); assembler;      {256 color palette}πasmπ    mov dx,03c8hπ    mov al,col             {color}π    out dx,alπ    inc dxπ    mov al,r               {red component}π    out dx,alπ    mov al,g               {green component}π    out dx,alπ    mov al,b               {blue component}π    out dx,alπend;πprocedure flip(srcscr, destscr : pScreen); assembler;   {copy screen}πasmπ    push dsπ    lds si,srcscrπ    les di,destscrπ    mov cx,pxsize*pysize/2π    rep movswπ    pop dsπend;πprocedure cls(scr : pScreen); assembler;   {clear screen}πasmπ    les di,scr;  xor ax,ax;  mov cx,pxsize*pysize/2;  rep stoswπend;πprocedure retrace; assembler;πasmπ        mov dx,03dahπ@vert1: in al,dxπ        test al,8π        jnz @vert1π@vert2: in al,dxπ        test al,8π        jz @vert2πend;πprocedure PutSprite(var sprite: SprRec; virseg: pScreen); assembler;πasmπ        push dsπ        lds si,sprite                   { get sprite segment }π        les di,virseg                   { get virtual screen segment }π        mov ax,SprRec[ds:si].yπ        shl ax,6π        mov di,axπ        shl ax,2π        add di,ax                       { y*pxsize }π        add di,SprRec[ds:si].x          { y*pxsize+x }π        mov dx,pxsize-xsize             { number of pixels left on line }π        lds si,SprRec[ds:si].bufπ        mov bx,ysizeπ@l1:    mov cx,xsizeπ@l0:    lodsbπ        or al,alπ        jz @skip                        { check if transparent "Black" }π        mov es:[di],al                  { draw it }π@skip:  inc diπ        dec cxπ        jnz @l0π        add di,dxπ        dec bxπ        jnz @l1π        pop dsπend;πprocedure OnlyVGA; assembler;πasmπ  @CheckForVga: {push    es}π                mov     AH,1ah         {Get Display Combination Code}π                mov     AL,00h         {AX := $1A00;}π                int     10h            {Intr($10, Regs);}π                cmp     AL,1ah         {IsVGA:= (AL=$1A) AND((BL=7) OR(BL=8))}π                jne     @NoVGAπ                cmp     BL,07h         {VGA w/ monochrome analog display}π                je      @VgaPresentπ                cmp     BL,08h         {VGA w/ color analog display}π                je      @VgaPresentπ  @NoVGA:π                mov     ax,3           {text mode}π                int     10hπ                push    csπ                pop     dsπ                lea     dx,@messageπ                mov     ah,9π                int     21h            {print $ terminated string}π                mov     ax,4c00hπ                int     21h            {terminate}π  @message:     db      'Sorry, but you need a VGA to see this!',10,13,24hπ  @VgaPresent:  {pop     es}π  {... After here is where your VGA code can execute}πend;  {OnlyVGA}ππVAR   n : byte;               {sprite number}π      hx,hy,i,j,k,np : integer;πBEGIN  {PROGRAM}π {Get text from command line and convert into a number}π Val(ParamStr(1), Population, Code);π if (Code <> 0)    {writeln('Bad number at position: ', Code);}π   OR (Population <1) OR (Population > maxsprites) thenπ   Population := maxsprites;    {default}π if ParamStr(1) = '?' thenπ   beginπ    writeln('Howard International, P.O. Box 34633, NKC, MO 64116 USA');π    writeln('1994 Freeware Sprite Game v1.2');π    writeln('Syntax:  spritegame.exe  [number]');π    writeln('         optional number is the total population of sprites (1 to 128)');π    halt;π   end;ππ {CharColor := Population;}π OnlyVGA;π SetMode($13);                  {320x200x256x1 plane}π Randomize;π vidscr := Ptr($A000,0);π New(virscr); cls(virscr); New(bgscr); cls(bgscr);π np := 128 div Population;π for i := 0 to Population-1 doπ  begin  {Define moire background pattern}π   case i mod 6 ofπ    0:beginπ       hx := 23;       hy := i*np;       n := 0;π      end;π    1:beginπ       hx := i*np;     hy := 23;         n := 0;π      end;π    2:beginπ       hx := i*np;     hy := 0;          n := 23;π      end;π    3:beginπ       hx := 23;       hy := 0;          n := i*np;π      end;π    4:beginπ       hx := 0;        hy := 23;         n := i*np;π      end;π    5:beginπ       hx:= 0;         hy:= i*np;        n := 23;π      end;π   end;π   for j := 0 to np-1 doπ    beginπ     k := j shr 1;π     SetPal(np*i+j+1, k+hx, k+hy, k+n);π    end;π  end;ππ for i := 1 to 127 do SetPal(127+i, i div 3, 20+i div 5, 20+i div 7);π for i := 0 to pxsize-1 do     {jh bug!  Reduce to legal screen limits}π   for j := 0 to pysize-1 doπ     bgscr^[j,i] := 128+ ABS(i*i - j*j) and 127;π(*π flip(bgscr, vidscr);               {copy background to video}π {SetPal(?,r,g,b)}                  {force a visible text palette entry}π writeln('Sprite Game v1.2 ');      {modify video}π flip(vidscr, bgscr);               {copy video to background}π*)π hx := xsize shr 1;π hy := ysize shr 1;π for n := 1 to Population doπ  beginπ   with sprite[n] doπ    beginπ     x := 20+ random(280 - xsize);π     y := 20+ random(160 - ysize);π     xspd := random(6) - 3;π     yspd := random(6) - 3;π     energy := random(10);         {punishes liberals}π     if xspd=0 thenπ       beginπ        xspd := 1;π        energy := random(20);      {average life expectancy}π       end;π     if yspd=0 thenπ       beginπ        yspd := 1;π        energy := random(40);      {rewards conservatives}π       end;π     New(buf);π     for i := 0 to xsize-1 doπ      for j := 0 to ysize-1 doπ       beginπ        k := (i-hx) * (i-hx) + (j-hy) * (j-hy);π        if (k< hx*hx) and (k> hx*hx div 16)π        then buf^[j,i] := k mod np  + np * (n-1)π        else buf^[j,i] := 0;       {CRT color "Black" is transparent}π       end;π    end; {with}π  end; {for}ππ  {jh Can store your own bitmap image in any sprite[n].buf^[j,i] such as: }π  for i := 0 to xsize-1 doπ    for j := 0 to ysize-1 doπ      beginπ        sprite[1].buf^[j,i] := j;           {first sprite.  Horizontal bars}π        sprite[Population].buf^[j,i] := i;  {last sprite.  Vertical bars}π      end;ππ  {jh Get characters from default font and attach to sprites}π  for i := 1 to CharRows doπ    for j := 1 to CharRows doπ      beginπ        for n := 1 to Population doπ          beginπ            {first hex digit for current sprite}π            if (CharSet[ord(HexDigits[n SHR 4]),i] shr (8-j) and 1 = 1) thenπ              sprite[n].buf^[i,j] := n       {CharColor}π            elseπ              sprite[n].buf^[i,j] := 0;      {transparent}π            {second hex digit for current sprite}π            if (CharSet[ord(HexDigits[n AND $F]),i] shr (8-j) and 1 =1) thenπ              sprite[n].buf^[i,j+CharRows] := n   {CharColor}π            elseπ              sprite[n].buf^[i,j+CharRows] := 0;  {transparent}π          end;π(* {mark last sprite 'Z'}π   sprite[Population].buf^[i,j] := CharSet[ord('Z'),i] shr (8-j) and 1; *)π      end;ππ  {jh Keep track of the last dead sprite and how old it was. }π  StartTimer;π  while not (KeyPressed or (dead=Population)) doπ  beginπ  flip(bgscr, virscr);π  retrace;π  dead := 0;                         {reset the sentinel}π  for n := 1 to Population doπ    with sprite[n] doπ    beginπ      if energy > 0 then PutSprite(sprite[n], virscr)     {show(n)}π      { else if energy < 0 then hide(n) }π      else inc(dead);π      inc(x,xspd);π      if (x<10) or (x > (310 - xsize)) thenπ      beginπ        xspd := -xspd;π        energy := energy - 1;π      end;π      inc(y,yspd);π      if (y<10) or (y > (190 - ysize)) thenπ      beginπ        yspd := -yspd;π        energy := energy - 1;π      end;π    end; {with}π  flip(virscr, vidscr);π  end; {while}ππ  StopTimer;π  survivor := 0;π  for n := 1 to Population doπ    begin                           {find last dead sprite with zero energy}π      if sprite[n].energy = 0 then survivor := n;π      Dispose(sprite[n].buf);π    end;π  Dispose(virscr);  Dispose(bgscr);π  SetMode($3);      {resume text video mode 3h= 80x25x16 color}π  writeln('Last dead sprite was # ', survivor, ' of ', Population);π  writeln('Time of death was ', trunc(StopClock));π  writeln('Life span was ', mins:2, ' Minute and ', secs:2, ' Seconds');πEND.   {PROGRAM}π                                                                                                                         26     08-24-9413:58ALL                      BAS VAN GAALEN           More STAR-ROUTINE        SWAG9408    
  2. Q╘≡    19     ╓   {πHowdy all!ππBy request here's the stars-routine, the final update. ;-)πLimits: cpu-speed and conv.-memory. No others...ππ}πprogram _stars;π{ Done by Sven van Heel and Bas van Gaalen, Holland, PD }πuses crt;πconstπ  f=6; nofstars=100; vidseg:word=$a000;π  bitmask:array[0..1,0..4,0..4] of byte=(π    ((0,0,1,0,0),(0,0,3,0,0),(1,3,6,3,1),(0,0,3,0,0),(0,0,1,0,0)),π    ((0,0,6,0,0),(0,0,3,0,0),(6,3,1,3,6),(0,0,3,0,0),(0,0,6,0,0)));πtype starstruc=recordπ  xp,yp:word; phase,col:byte; dur:shortint; active:boolean; end;πvar stars:array[1..nofstars] of starstruc;ππprocedure setpal(col,r,g,b : byte); assembler; asmπ  mov dx,03c8h; mov al,col; out dx,al; inc dx; mov al,rπ  out dx,al; mov al,g; out dx,al; mov al,b; out dx,al; end;ππprocedure retrace; assembler; asmπ  mov dx,3dah; @vert1: in al,dx; test al,8; jz @vert1π  @vert2: in al,dx; test al,8; jnz @vert2; end;ππvar i,x,y:word;πbeginπ  asm mov ax,13h; int 10h; end;π  for i:=1 to 10 do beginπ    setpal(i,f*i,0,0); setpal(21-i,f*i,0,0); setpal(20+i,0,0,0);π    setpal(30+i,0,f*i,0); setpal(51-i,0,f*i,0); setpal(50+i,0,0,0);π    setpal(60+i,0,0,f*i); setpal(81-i,0,0,f*i); setpal(80+i,0,0,0);π    setpal(90+i,f*i,f*i,0); setpal(111-i,f*i,f*i,0); setpal(110+i,0,0,0);π    setpal(120+i,0,f*i,f*i); setpal(141-i,0,f*i,f*i); setpal(140+i,0,0,0);π    setpal(150+i,f*i,f*i,f*i); setpal(171-i,f*i,f*i,f*i); setpal(170+i,0,0,0);π  end;π  randomize;π  for i:=1 to nofstars do with stars[i] do beginπ    xp:=0; yp:=0; col:=0; phase:=0;π    dur:=random(20);π    active:=false;π  end;π  repeatπ    retrace; retrace;π    {setpal(0,0,0,30);}π    for i:=1 to nofstars do with stars[i] do beginπ      dec(dur);π      if (not active) and (dur<0) then beginπ        active:=true; phase:=0; col:=30*random(6);π        xp:=random(315); yp:=random(195);π      end;π    end;π    for i:=1 to nofstars do with stars[i] doπ      if active then beginπ        for x:=0 to 4 do for y:=0 to 4 doπ          if bitmask[byte(phase>10),x,y]>0 thenπ            mem[vidseg:(yp+y)*320+xp+x]:=bitmask[byte(phase>10),x,y]+col+phase;π        inc(phase);π        if phase=20 then begin active:=false; dur:=random(20); end;π      end;π    setpal(0,0,0,0);π  until keypressed;π  textmode(lastmode);πend.π                                                                                      27     08-24-9417:50ALL                      ERIC COOLMAN             Another Fire Graphic     SWAG9408    ╔V·    67     ╓   {πAC>I got my hands on Jare's fire code and thought it was pretty cool,πAC>so I made my own fire program. Although it didn't turn out like IπAC>thought it would (like Jare's) what I have is (at least I think so)πAC>something that looks more realistic.ππThis is kinda funny... just the other day I was looking at Jare's fireπcode, and did an 80x50 textmode version of it in C.  I did a quick andπdirty conversion of it to Pascal so I could post it here for youπ(don't you feel special? <G>).  The pascal version came out a bitπslower then my C version, although they are very similar. I haven'tπfigured out why though... most times I try this, both come out closeπto the same speed.ππ(********************************************************************π Fire by Eric Coolman (aka. Digitar/SKP), Simple Minded Softwareπ Much like Jare's (VangelisTeam) fire, but uses 80x50x16 text modeπ rather than 320x200x256 (which was "tweaked" to look like 80x50π text mode).  Reference : FIRE.TXT by Phil Carlisle (aka Zoombapup,π CodeX) from PC Game Programmer's Encyclopedia (PCGPE10.ZIP) by Markπ Feldman and contributers (thanks for the great reads guys!).π Compiler : Turbo Pascal 6.0π Released to public domain, July 30, 1994.ππ NOTE: FirePalette will not get loaded if running under DESQviewπ       with "VIRTUALIZE TEXTMODE" on (which will stop any paletteπ       manipulation).  To fix, go into setup for the DOSBOX, andπ       under "VIRTUALIZE TEXT/GRAPHICS" mode, and set it to "N".π       Also for DV, set "WRITES DIRECT TO SCREEN" to "Y"es.π********************************************************************)π}ππProgram tFire;ππconstπ    MAXX = 80;π    MAXY = 50;π    { Our gradient firepalette (white/yellow/red/orange/slate/black) }π    FirePal : array[0..3*16-1] of byte =π      {       [ HUES ]       }π      {  RED    GREEN   BLUE }π      {  ===    =====   ==== }π      (                                               { Normal Color }π         0,     0,      0,                            { BLACK        }π         0,     5,      3,                            { BLUE         }π         0,     6,      7,                            { GREEN        }π         0,     7,      9,                            { CYAN         }π         0,     8,      11,                           { RED          }π         0,     9,      12,                           { MAGENTA      }π         63,    13,     0,                            { BROWN        }π         60,    4,      4,                            { LIGHTGRAY    }π         63,    58,     21,                           { DARKGRAY     }π         63,    59,     0,                            { LIGHTBLUE    }π         63,    60,     0,                            { LIGHTGREEN   }π         63,    60,     0,                            { LIGHTCYAN    }π         63,    61,     30,                           { LIGHTRED     }π         63,    55,     42,                           { LIGHTMAGENTA }π         63,    60,     55,                           { YELLOW       }π         63,    63,     63                            { WHITE        }π     );ππtypeπ     ColorArray = array [0..MAXX+1, 0..MAXY] of Byte;πvarπ    FireImage : ColorArray;π    CUR       : Word;                                { working color }π    x, y      : Byte;                             { general counters }ππ(*π Sets video mode.  If mode is 64d (40h), 8x8 ROM font will be loadedπ and 80x50 textmode will be activated.  Any other value will setπ mode normally.π*)πprocedure VidMode(mode : byte); assembler;πasmπ     cmp  mode, 40h                      { (64d) want 80x50/43 mode? }π     jnz  @normalsetπ     mov  ax,1112h                { set 8 point font as current font }π     mov  bl,00hπ     jmp  @MakeItSo                                            { ;-) }π   @normalset:π     mov  ah, 00hπ     mov  al, modeπ   @MakeItSo:π     int  10hπend;ππ{ grabs and dumps keypress...returns 1 if a key was hit, else 0 }πfunction KbGrab : boolean;πvarπ    WasHit : boolean;πbeginπ    WasHit := False;ππ    asmπ        mov ax, 0100hπ        int 16hπ        lahfπ        test ah, 40hπ        jnz @doneπ        inc WasHitπ        mov ax, 0000h                  { grab the key they hit .... }π        int 16hπ      @done:π    end;π    KbGrab := WasHit;πend;ππ(*********************************************************************π sets only color indexes normally used in textmode (16 of 'em).π Note the heavy use of ternary operator there... what that meansπ is - indexes 7 to 15 (dark gray to white) are actually indexesπ 55 to 63, and index 6 (dark brown) is actually 20d (14h) becauseπ it uses the secondary hues so that it doesn't look too much likeπ red.  The rest (0,1,2,4,5,7) are as expected.π*********************************************************************)πprocedure SetFirePal;πvarπ  i, j : Byte;πbeginπ   for i:= 0 to 16 do                               { for each index }π     beginπ       if i <= 7 then begin if i = 6 then j := 20 else j := i; endπ       else j := i+48;π       port[$3c8] := j;                             { Send the index }π       port[$3c9] := FirePal[i*3];                    { Send the red }π       port[$3c9] := FirePal[i*3+1];                { Send the green }π       port[$3c9] := FirePal[i*3+2];                 { Send the blue }π    end;πend;πππ(*********************************************************************π  +----+-----+----+ Table to left are screen ofs's surrounding CUR(0).π  |-81 | -80 |-79 | That we will take average of. 80 is for width ofπ  +----+-----+----+ screen in chars in textmode (also width of ourπ  | -1 | CUR | +1 | screen buffer).  The calculated average will beπ  +----+-----+----+ assigned to spot '-80' to move the fire upwards,π  |+79 | +80 |+81 | and decremented to fade it out (like a plasmaπ  +----+-----+----+ effect somewhat).π*********************************************************************)πprocedure DoFire;πbegin;π    { start at [1,1] or above because 0,0 doesn't have 8 surrounding }π    { stop x at 78 or less for the same reason (ending y doesn't     }π    { matter cause we are setting max y randomly anyways).           }π    { (starting y can be set to 8 to give room for a scroller).      }π     for y := 1 to MAXY doπ       for x := 1 to MAXX-1 doπ         beginπ          { get average of 8 surrounding colors              (-ofs-) }π          CUR := (  FireImage[x-1][y]         { direct to left  (-1) }π                  + FireImage[x+1][y]         { direct to right (+1) }π                  + FireImage[x][y-1]         { direct above   (-80) }π                  + FireImage[x][y+1]         { direct below   (+80) }π                  + FireImage[x-1][y-1]       { above to left  (-81) }π                  + FireImage[x+1][y+1]       { below to right (+81) }π                  + FireImage[x+1][y-1]       { above to right (-79) }π                  + FireImage[x-1][y+1]       { below to left  (+79) }π                ) shr 3;                      { divide by 8          }π         Dec(CUR);                            { make fire fade out   }π         { notice below is assigning the average CUR to (CUR-1 line) }π         { ... this keeps fire moving in upward direction.           }π         FireImage[x][y-1] := CUR;                       { set color }π         mem[$b800:y*160+(x shl 1)+1] := FireImage[x][y];π       end;ππ       { Randomly set last line of fire... This keeps the fire going }π      for x := 0 to 80 doπ         FireImage[x][49] := (random(255)+1);π      { second last line also to give fire some more height. }π      for x := 0 to 80 doπ         FireImage[x][48] := (random(255)+1);πend;ππbeginπ   VidMode($03);                     { 80x25 mode (to clear screen) }π   VidMode($40);                                       { 80x50 mode }ππ   SetFirePal;ππ  { change to hi-intense background so we have 16 bg colors to }π  { work with.                                                 }π  asmπ      mov ax, 1003h                                 { blinking attr }π      mov bx, 0000h            { 0=HiIntBackground, 1=Blinking Attr }π      int 10hπ  end;ππ  { clear fire image }π  fillchar(FireImage, sizeof(FireImage), 63);     { fill with white }ππ  for x := 0 to 80 do          { set up last line to start the fire }π    FireImage[x][49] := (random(255)+1);ππ  repeat DoFire; until KbGrab;ππ  VidMode($03);                                        { 80x25 mode }πend.π                                                         28     08-24-9417:53ALL                      DAVID DAHL               Transparent 3D Vectors   SWAG9408    ┬d    173    ╓   πProgram TrnsVect; { Transparent Vectors }π{$G+} { 286 Instructions Enabled }ππ{  Transparent 3D Vectors Example  }π{     Programmed by David Dahl     }π{  This program is PUBLIC DOMAIN   }ππUses CRT;πConst ViewerDist = 200;πType VGAArray = Array [0..199, 0..319] of Byte;π     VGAPtr   = ^VGAArray;π     PaletteRec  = Recordπ                         Red   : Byte;π                         Green : Byte;π                         Blue  : Byte;π                   End;π     PaletteType = Array [0..255] of PaletteRec;π     PalettePtr  = ^PaletteType;π     PolyRaster  = Recordπ                         X1 : Word;π                         X2 : Word;π                   End;π     PolyFill    = Array [0..199] of PolyRaster;π     PolyFillPtr = ^PolyFill;π     FacetPtr     = ^PolyFacet;π     PolyFacet    = Recordπ                          Color       : Byte;π                          X1, Y1, Z1,π                          X2, Y2, Z2,π                          X3, Y3, Z3,π                          X4, Y4, Z4  : Integer;π                          NextFacet   : FacetPtr;π                    End;π     PolyHPtr     = ^PolygonHead;π     PolygonHead  = Recordπ                          X, Y, Z    : Integer;π                          AX, AY, AZ : Integer;π                          FirstFacet : FacetPtr;π                    End;πVar  VGAMEM   : VGAPtr;π     WorkPage : VGAPtr;π     BkgPage  : VGAPtr;π     Palette  : PalettePtr;π     PolyList : PolyFillPtr;π{-[ Initialize 320 X 200 X 256 VGA ]---------------------------------------}πProcedure GoMode13h; Assembler;πASMπ   MOV AX, $0013π   INT $10πEnd;π{=[ Convex Polygon Drawing Routines ]======================================}π{-[ Clear Polygon Raster List ]--------------------------------------------}πProcedure ClearPolyList (Var ListIn : PolyFill);πBeginπ     FillChar (ListIn, SizeOf(ListIn), $FF);πEnd;π{-[ OR VariableIn with Value -- Modeled after FillChar ]-------------------}πProcedure ORChar (Var VariableIn;π                      Size       : Word;π                      Value      : Byte); Assembler;πASMπ   PUSH DSπ   MOV CX, Sizeπ   OR  CX, CXπ   JZ  @Doneπ   LDS SI, VariableInπ   MOV AL, Valueπ   @ORLoop:π      OR DS:[SI], ALπ      INC SIπ   LOOP @ORLoopπ   @Done:π   POP DSπEnd;π{-[ Draw Polygon From Raster List To Work Buffer ]-------------------------}πProcedure DrawPolyFromList (Var ListIn      : PolyFill;π                            Var FrameBuffer : VGAArray;π                                Color       : Byte);πVar YCount : Word;π    TempX1 : Word;π    TempX2 : Word;πBeginπ     For YCount := 0 to 199 doπ     Beginπ          TempX1 := ListIn[YCount].X1;π          TempX2 := ListIn[YCount].X2;π          If (TempX1 <= 319) AND (TempX2 <= 319)π          Thenπ              ORChar (FrameBuffer[YCount, TempX1],π                      TempX2 - TempX1 + 1, Color);π     End;πEnd;π{-[ Add An Element To The Raster List ]------------------------------------}πProcedure AddRasterToPoly (Var ListIn : PolyFill;π                               X, Y   : Integer);πBeginπ     { Clip X }π     If X < 0π     Thenπ         X := 0π     Elseπ         If X > 319π         Thenπ             X := 319;π    { If Y in bounds, add to list }π    If ((Y >= 0) AND (Y <= 199))π    Thenπ    Beginπ         If (ListIn[Y].X1 > 319)π         Thenπ         Beginπ             ListIn[Y].X1 := X;π             ListIn[Y].X2 := X;π         Endπ         Elseπ             If (X < ListIn[Y].X1)π             Thenπ                 ListIn[Y].X1 := Xπ             Elseπ                 If (X > ListIn[Y].X2)π                 Thenπ                     ListIn[Y].X2 := X;π    End;πEnd;π{=[ Polygon ]==============================================================}π{-[ Add A Facet To Current Polygon ]---------------------------------------}πProcedure AddFacet (Polygon          : PolyHPtr;π                    Color            : Byte;π                    X1In, Y1In, Z1In : Integer;π                    X2In, Y2In, Z2In : Integer;π                    X3In, Y3In, Z3In : Integer;π                    X4In, Y4In, Z4In : Integer);πVar CurrentFacet : FacetPtr;πBeginπ     If Polygon^.FirstFacet = Nilπ     Thenπ     Beginπ          New(Polygon^.FirstFacet);π          CurrentFacet := Polygon^.FirstFacet;π     Endπ     Elseπ     Beginπ          CurrentFacet := Polygon^.FirstFacet;π          While CurrentFacet^.NextFacet <> Nil doπ                CurrentFacet := CurrentFacet^.NextFacet;π          New(CurrentFacet^.NextFacet);π          CurrentFacet := CurrentFacet^.NextFacet;π     End;π     CurrentFacet^.Color := Color;π     CurrentFacet^.X1 := X1In;π     CurrentFacet^.X2 := X2In;π     CurrentFacet^.X3 := X3In;π     CurrentFacet^.X4 := X4In;π     CurrentFacet^.Y1 := Y1In;π     CurrentFacet^.Y2 := Y2In;π     CurrentFacet^.Y3 := Y3In;π     CurrentFacet^.Y4 := Y4In;π     CurrentFacet^.Z1 := Z1In;π     CurrentFacet^.Z2 := Z2In;π     CurrentFacet^.Z3 := Z3In;π     CurrentFacet^.Z4 := Z4In;π     CurrentFacet^.NextFacet := Nil;πEnd;π{-[ Initialize a New Polygon ]---------------------------------------------}πProcedure InitializePolygon (Var PolyHead               : PolyHPtr;π                                 XIn, YIn, ZIn          : Integer;π                                 RollIn, PitchIn, YawIn : Integer);πBeginπ     If PolyHead = Nilπ     Thenπ     Beginπ          New(PolyHead);π          PolyHead^.X := XIn;π          PolyHead^.Y := YIn;π          PolyHead^.Z := ZIn;π          PolyHead^.AX := RollIn;π          PolyHead^.AY := PitchIn;π          PolyHead^.AZ := YawIn;π          PolyHead^.FirstFacet := Nil;π     End;πEnd;π{-[ Dispose Polygon ]------------------------------------------------------}πProcedure DisposePolygon (Var PolyHead : PolyHPtr);πVar TempPtr : FacetPtr;π    TP2     : FacetPtr;πBeginπ     TempPtr := PolyHead^.FirstFacet;π     While TempPtr <> Nil doπ     Beginπ          TP2 := TempPtr^.NextFacet;π          Dispose (TempPtr);π          TempPtr := TP2;π     End;π     Dispose (PolyHead);π     PolyHead := Nil;πEnd;π{-[ Rotate Polygon About Axies ]-------------------------------------------}πProcedure RotatePolygon (Var PolyHead   : PolyHPtr;π                             DX, DY, DZ : Integer);πBeginπ     INC (PolyHead^.AX, DX);π     INC (PolyHead^.AY, DY);π     INC (PolyHead^.AZ, DZ);π     While (PolyHead^.AX > 360) doπ           DEC(PolyHead^.AX, 360);π     While (PolyHead^.AY > 360) doπ           DEC(PolyHead^.AY, 360);π     While (PolyHead^.AZ > 360) doπ           DEC(PolyHead^.AZ, 360);π     While (PolyHead^.AX < -360) doπ           INC(PolyHead^.AX, 360);π     While (PolyHead^.AY < -360) doπ           INC(PolyHead^.AY, 360);π     While (PolyHead^.AZ < -360) doπ           INC(PolyHead^.AZ, 360);πEnd;π{=[ Graphics Related Routines ]============================================}π{-[ Build Facet Edge ]-----------------------------------------------------}πProcedure DrawLine (X1In, Y1In,π                    X2In, Y2In  : Integer;π                    Color       : Byte);πVar dx, dy : Integer;π    ix, iy : Integer;π    X,  Y  : Integer;π    PX, PY : Integer;π    i      : Integer;π    incc   : Integer;π    plot   : Boolean;πBeginπ     dx := X1In - X2In;π     dy := Y1In - Y2In;π     ix := abs(dx);π     iy := abs(dy);π     X  := 0;π     Y  := 0;π     PX := X1In;π     PY := Y1In;π     AddRasterToPoly (PolyList^, PX, PY);π     If ix > iyπ     Thenπ         incc := ixπ     Elseπ         incc := iy;π     i := 0;π     While (i <= incc) doπ     Beginπ          Inc (X, ix);π          Inc (Y, iy);π          Plot := False;π          If X > inccπ          Thenπ          Beginπ               Plot := True;π               Dec (X, incc);π               If dx < 0π               Thenπ                   Inc(PX)π               Elseπ                   Dec(PX);π          End;π          If Y > inccπ          Thenπ          Beginπ               Plot := True;π               Dec (Y, incc);π               If dy < 0π               Thenπ                   Inc(PY)π               Elseπ                   Dec(PY);π          End;π          If Plotπ          Thenπ              AddRasterToPoly (PolyList^, PX, PY);π          Inc(i);π     End;πEnd;π{-[ Draw Polygon ]---------------------------------------------------------}πProcedure DrawPolygon3D (PolyHead : PolyHPtr;π                         Buffer   : VGAPtr);πVar CurrentFacet               : FacetPtr;π    CalcX1, CalcY1, CalcZ1,π    CalcX2, CalcY2, CalcZ2,π    CalcX3, CalcY3, CalcZ3,π    CalcX4, CalcY4, CalcZ4     : Integer;π    XPrime1, YPrime1, ZPrime1,π    XPrime2, YPrime2, ZPrime2,π    XPrime3, YPrime3, ZPrime3,π    XPrime4, YPrime4, ZPrime4  : Integer;π    Temp                       : Integer;π    CTX, STX,π    CTY, STY,π    CTZ, STZ  : Real;πBeginπ     CurrentFacet := PolyHead^.FirstFacet;π     While CurrentFacet <> Nil doπ       With CurrentFacet^ doπ       Beginπ            ClearPolyList (PolyList^);π            XPrime1 := X1; YPrime1 := Y1; ZPrime1 := Z1;π            XPrime2 := X2; YPrime2 := Y2; ZPrime2 := Z2;π            XPrime3 := X3; YPrime3 := Y3; ZPrime3 := Z3;π            XPrime4 := X4; YPrime4 := Y4; ZPrime4 := Z4;π            { Rotate Coords }π            CTX := COS(PolyHead^.AX * PI / 180);π            STX := SIN(PolyHead^.AX * PI / 180);π            CTY := COS(PolyHead^.AY * PI / 180);π            STY := SIN(PolyHead^.AY * PI / 180);π            CTZ := COS(PolyHead^.AZ * PI / 180);π            STZ := SIN(PolyHead^.AZ * PI / 180);π            Temp    := Round((YPrime1 * CTX) - (ZPrime1 * STX));π            ZPrime1 := Round((YPrime1 * STX) + (ZPrime1 * CTX));π            YPrime1 := Temp;π            Temp    := Round((XPrime1 * CTY) - (ZPrime1 * STY));π            ZPrime1 := Round((XPrime1 * STY) + (ZPrime1 * CTY));π            XPrime1 := Temp;π            Temp    := Round((XPrime1 * CTZ) - (YPrime1 * STZ));π            YPrime1 := Round((XPrime1 * STZ) + (YPrime1 * CTZ));π            XPrime1 := Temp;π            Temp    := Round((YPrime2 * CTX) - (ZPrime2 * STX));π            ZPrime2 := Round((YPrime2 * STX) + (ZPrime2 * CTX));π            YPrime2 := Temp;π            Temp    := Round((XPrime2 * CTY) - (ZPrime2 * STY));π            ZPrime2 := Round((XPrime2 * STY) + (ZPrime2 * CTY));π            XPrime2 := Temp;π            Temp    := Round((XPrime2 * CTZ) - (YPrime2 * STZ));π            YPrime2 := Round((XPrime2 * STZ) + (YPrime2 * CTZ));π            XPrime2 := Temp;π            Temp    := Round((YPrime3 * CTX) - (ZPrime3 * STX));π            ZPrime3 := Round((YPrime3 * STX) + (ZPrime3 * CTX));π            YPrime3 := Temp;π            Temp    := Round((XPrime3 * CTY) - (ZPrime3 * STY));π            ZPrime3 := Round((XPrime3 * STY) + (ZPrime3 * CTY));π            XPrime3 := Temp;π            Temp    := Round((XPrime3 * CTZ) - (YPrime3 * STZ));π            YPrime3 := Round((XPrime3 * STZ) + (YPrime3 * CTZ));π            XPrime3 := Temp;π            Temp    := Round((YPrime4 * CTX) - (ZPrime4 * STX));π            ZPrime4 := Round((YPrime4 * STX) + (ZPrime4 * CTX));π            YPrime4 := Temp;π            Temp    := Round((XPrime4 * CTY) - (ZPrime4 * STY));π            ZPrime4 := Round((XPrime4 * STY) + (ZPrime4 * CTY));π            XPrime4 := Temp;π            Temp    := Round((XPrime4 * CTZ) - (YPrime4 * STZ));π            YPrime4 := Round((XPrime4 * STZ) + (YPrime4 * CTZ));π            XPrime4 := Temp;π            { Translate Coords }π            XPrime1 := PolyHead^.X + XPrime1;π            YPrime1 := PolyHead^.Y + YPrime1;π            ZPrime1 := PolyHead^.Z + ZPrime1;π            XPrime2 := PolyHead^.X + XPrime2;π            YPrime2 := PolyHead^.Y + YPrime2;π            ZPrime2 := PolyHead^.Z + ZPrime2;π            XPrime3 := PolyHead^.X + XPrime3;π            YPrime3 := PolyHead^.Y + YPrime3;π            ZPrime3 := PolyHead^.Z + ZPrime3;π            XPrime4 := PolyHead^.X + XPrime4;π            YPrime4 := PolyHead^.Y + YPrime4;π            ZPrime4 := PolyHead^.Z + ZPrime4;π            { Translate 3D Vectorspace to 2D Framespace }π            CalcX1 := 160 + ((LongInt(XPrime1)*ViewerDist) DIVπ                             (ZPrime1+ViewerDist));π            CalcY1 := 100 + ((LongInt(YPrime1)*ViewerDist) DIVπ                             (ZPrime1+ViewerDist));π            CalcX2 := 160 + ((LongInt(XPrime2)*ViewerDist) DIVπ                             (ZPrime2+ViewerDist));π            CalcY2 := 100 + ((LongInt(YPrime2)*ViewerDist) DIVπ                             (ZPrime2+ViewerDist));π            CalcX3 := 160 + ((LongInt(XPrime3)*ViewerDist) DIVπ                             (ZPrime3+ViewerDist));π            CalcY3 := 100 + ((LongInt(YPrime3)*ViewerDist) DIVπ                             (ZPrime3+ViewerDist));π            CalcX4 := 160 + ((LongInt(XPrime4)*ViewerDist) DIVπ                             (ZPrime4+ViewerDist));π            CalcY4 := 100 + ((LongInt(YPrime4)*ViewerDist) DIVπ                             (ZPrime4+ViewerDist));π            { Draw Shape }π            DrawLine (CalcX1, CalcY1, CalcX2, CalcY2, Color);π            DrawLine (CalcX2, CalcY2, CalcX3, CalcY3, Color);π            DrawLine (CalcX3, CalcY3, CalcX4, CalcY4, Color);π            DrawLine (CalcX4, CalcY4, CalcX1, CalcY1, Color);π            DrawPolyFromList (PolyList^, WorkPage^, Color);π            CurrentFacet := CurrentFacet^.NextFacet;π       End;πEnd;π{-[ Build Background ]-----------------------------------------------------}πProcedure BuildBackground (Var BufferIn : VGAArray);πVar CounterX,π    CounterY  : Integer;πBeginπ     For CounterY := 0 to 199 doπ      For CounterX := 0 to 319 doπ          BufferIn[CounterY, CounterX] := 1 + ((CounterY MOD 5) * 5) +π                                               (CounterX MOD 5);πEnd;π{-[ Build Palette ]--------------------------------------------------------}πProcedure BuildPalette (Var PaletteOut : PaletteType);πConst BC = 16;πVar Counter1,π    Counter2  : Integer;πBeginπ     FillChar (PaletteOut, SizeOf(PaletteOut), 0);π     For Counter1 := 0 to 4 doπ     For Counter2 := 1 to 2 doπ     Beginπ          PaletteOut[1+(Counter1 * 5)+Counter2].Red   := BC+(Counter2 * 5);π          PaletteOut[1+(Counter1 * 5)+Counter2].Green := BC+(Counter2 * 5);π          PaletteOut[1+(Counter1 * 5)+Counter2].Blue  := BC+(Counter2 * 5);π          PaletteOut[1+(Counter1 * 5)+4-Counter2].Red   := BC+(Counter2 * 5);π          PaletteOut[1+(Counter1 * 5)+4-Counter2].Green := BC+(Counter2 * 5);π          PaletteOut[1+(Counter1 * 5)+4-Counter2].Blue  := BC+(Counter2 * 5);π     End;π     For Counter1 := 0 to 4 doπ     Beginπ          If PaletteOut[1+(5 * 1)+Counter1].Red < BC + 5π          Thenπ          Beginπ              PaletteOut[1+(5 * 1)+Counter1].Red   := BC + 5;π              PaletteOut[1+(5 * 1)+Counter1].Green := BC + 5;π              PaletteOut[1+(5 * 1)+Counter1].Blue  := BC + 5;π              PaletteOut[1+(5 * 3)+Counter1].Red   := BC + 5;π              PaletteOut[1+(5 * 3)+Counter1].Green := BC + 5;π              PaletteOut[1+(5 * 3)+Counter1].Blue  := BC + 5;π          End;π          PaletteOut[1+(5 * 2)+Counter1].Red   := BC + 10;π          PaletteOut[1+(5 * 2)+Counter1].Green := BC + 10;π          PaletteOut[1+(5 * 2)+Counter1].Blue  := BC + 10;π     End;π     For Counter1 := 0 to 24 doπ     Beginπ      PaletteOut[32+Counter1].Red   := ((PaletteOut[Counter1].Red* 8)+π                                        (26 * 24)) DIV 32;π      PaletteOut[32+Counter1].Green := ((PaletteOut[Counter1].Green* 8)+π                                        (0  * 24)) DIV 32;π      PaletteOut[32+Counter1].Blue  := ((PaletteOut[Counter1].Blue* 8)+π                                        (0  * 24)) DIV 32;π      PaletteOut[64+Counter1].Red   := ((PaletteOut[Counter1].Red* 8)+π                                        (0  * 24)) DIV 32;π      PaletteOut[64+Counter1].Green := ((PaletteOut[Counter1].Green* 8)+π                                        (26 * 24)) DIV 32;π      PaletteOut[64+Counter1].Blue  := ((PaletteOut[Counter1].Blue* 8)+π                                        (0  * 24)) DIV 32;π      PaletteOut[128+Counter1].Red   := ((PaletteOut[Counter1].Red* 8)+π                                        (0  * 24)) DIV 32;π      PaletteOut[128+Counter1].Green := ((PaletteOut[Counter1].Green* 8)+π                                        (0  * 24)) DIV 32;π      PaletteOut[128+Counter1].Blue  := ((PaletteOut[Counter1].Blue* 8)+π                                        (26 * 24)) DIV 32;π      PaletteOut[32+64+Counter1].Red   := ((PaletteOut[Counter1].Red* 6)+π                                        (23 * 26)) DIV 32;π      PaletteOut[32+64+Counter1].Green := ((PaletteOut[Counter1].Green* 6)+π                                        (23 * 26)) DIV 32;π      PaletteOut[32+64+Counter1].Blue  := ((PaletteOut[Counter1].Blue* 6)+π                                        (0  * 26)) DIV 32;π      PaletteOut[32+128+Counter1].Red   := ((PaletteOut[Counter1].Red* 6)+π                                        (23 * 26)) DIV 32;π      PaletteOut[32+128+Counter1].Green := ((PaletteOut[Counter1].Green* 6)+π                                        (0  * 26)) DIV 32;π      PaletteOut[32+128+Counter1].Blue  := ((PaletteOut[Counter1].Blue* 6)+π                                        (23 * 26)) DIV 32;π      PaletteOut[64+128+Counter1].Red   := ((PaletteOut[Counter1].Red* 6)+π                                        (0  * 26)) DIV 32;π      PaletteOut[64+128+Counter1].Green := ((PaletteOut[Counter1].Green* 6)+π                                        (23 * 26)) DIV 32;π      PaletteOut[64+128+Counter1].Blue  := ((PaletteOut[Counter1].Blue* 6)+π                                        (23 * 26)) DIV 32;π     End;πEnd;π{-[ Move Background by Moving Palette ]------------------------------------}πProcedure MoveBackground (Var PaletteIn : PaletteType);πVar TempPal : Array[0..5] of PaletteRec;πBeginπ     {-- Move Background Colors --}π     Move (PaletteIn[1], TempPal[0], 5 * 3);π     Move (PaletteIn[1+5], PaletteIn[1], ((5 * 4) * 3));π     Move (TempPal[0], PaletteIn[1 + (5 * 4)], 5 * 3);π     {-- Move See-Through Colors --}π     { Red }π     Move (PaletteIn[32], TempPal[0], 6 * 3);π     Move (PaletteIn[32+5], PaletteIn[32], ((5 * 4) * 3));π     Move (TempPal[0], PaletteIn[32 + (5 * 4)], 6 * 3);π     { Green }π     Move (PaletteIn[64], TempPal[0], 6 * 3);π     Move (PaletteIn[64+5], PaletteIn[64], ((5 * 4) * 3));π     Move (TempPal[0], PaletteIn[64 + (5 * 4)], 6 * 3);π     { Blue }π     Move (PaletteIn[128], TempPal[0], 6 * 3);π     Move (PaletteIn[128+5], PaletteIn[128], ((5 * 4) * 3));π     Move (TempPal[0], PaletteIn[128 + (5 * 4)], 6 * 3);π     { Red + Green }π     Move (PaletteIn[(32 OR 64)], TempPal[0], 6 * 3);π     Move (PaletteIn[(32 OR 64)+5], PaletteIn[(32 OR 64)], ((5 * 4) * 3));π     Move (TempPal[0], PaletteIn[(32 OR 64) + (5 * 4)], 6 * 3);π     { Red + Blue }π     Move (PaletteIn[(32 OR 128)], TempPal[0], 6 * 3);π     Move (PaletteIn[(32 OR 128)+5], PaletteIn[(32 OR 128)], ((5 * 4) * 3));π     Move (TempPal[0], PaletteIn[(32 OR 128) + (5 * 4)], 6 * 3);π     { Green + Blue }π     Move (PaletteIn[(64 OR 128)], TempPal[0], 6 * 3);π     Move (PaletteIn[(64 OR 128)+5], PaletteIn[(64 OR 128)], ((5 * 4) * 3));π     Move (TempPal[0], PaletteIn[(64 OR 128) + (5 * 4)], 6 * 3);πEnd;π{-[ Set Palette ]----------------------------------------------------------}πProcedure SetPalette (Var PaletteIn : PaletteType); Assembler;πASMπ   PUSH DSπ   LDS SI, PaletteIn { Sets whole palette at once...       }π   MOV CX, 256 * 3   {  *NOT* good practice since many VGA }π   MOV DX, 03DAh     {  cards will show snow at the top of }π   @WaitNotVSync:    {  of the screen.  It's done here     }π     IN  AL, DX      {  'cause the background animation    }π     AND AL, 8       {  requires large ammounts of the     }π   JNZ @WaitNotVSync {  palette to be updated every new    }π   @WaitVSync:       {  frame.                             }π     IN  AL, DXπ     AND AL, 8π   JZ @WaitVSyncπ   XOR AX, AXπ   MOV DX, 03C8hπ   OUT DX, ALπ   INC DXπ   @PaletteLoop:π     LODSBπ     OUT DX, ALπ   LOOP @PaletteLoopπ   POP DSπEnd;π{=[ Main Program ]=========================================================}πVar Polygon1 : PolyHPtr;πBeginπ     VGAMEM := Ptr($A000, $0000);π     New (WorkPage);π     New (BkgPage);π     New (Palette);π     New (PolyList);π     ClearPolyList (PolyList^);π     GoMode13h;π     BuildBackground (BkgPage^);π     BuildPalette    (Palette^);π     SetPalette (Palette^);π     Polygon1 := Nil;π     InitializePolygon (Polygon1,  { Polygon List Head         }π                        0, 0, 60,  { X, Y, Z of polygon        }π                        0, 0, 0);  { Iniitial Roll, Pitch, Yaw }π     AddFacet (Polygon1,       { Polygon List Head        }π                32,            { Color                    }π               -40, -40,  50,  { One Corner of Polygon    }π                40, -40,  50,  { Second Corner of Polygon }π                40,  40,  50,  { Third Corner of Polygon  }π               -40,  40,  50); { Last Corner of Polygon   }π     AddFacet (Polygon1,π                64,π               -50, -40, -40,π               -50, -40,  40,π               -50,  40,  40,π               -50,  40, -40);π     AddFacet (Polygon1,π               128,π                40, -50, -40,π                40, -50,  40,π               -40, -50,  40,π               -40, -50, -40);π     Repeatπ           { Clear Workpage }π           WorkPage^ := BkgPage^;π           ClearPolyList (PolyList^);π           DrawPolygon3D (Polygon1,    { Polygon Definition }π                          WorkPage);   { Work buffer        }π           MoveBackground (Palette^);π           SetPalette     (Palette^);π           { Display Work Buffer }π           VGAMEM^ := WorkPage^;π           RotatePolygon (Polygon1,π                          5, 10, 1);π     Until Keypressed;π     DisposePolygon (Polygon1);π     Dispose (PolyList);π     Dispose (Palette);π     Dispose (BkgPage);π     Dispose (WorkPage);π     TextMode (C80);πEnd.π                                                                                      29     08-24-9417:53ALL                      GARTH KRUMINS            GRAPHICS ROUTINES        SWAG9408    5    12     ╓   {here are some assembler routines for the 320x200x256 mode.}ππusesπ crt;ππPROCEDURE InitVGA; ASSEMBLER;πasmπ   mov  ax, 13hπ   int  10hπend;ππPROCEDURE InitTEXT; ASSEMBLER;πasmπ   mov  ax, 03hπ   int  10hπend;ππPROCEDURE PlotPixel1(X, Y: Word; Color: Byte); ASSEMBLER;πasmπ   push esπ   push diπ   mov  ax, Yπ   mov  bx, axπ   shl  ax, 8π   shl  bx, 6π   add  ax, bxπ   add  ax, Xπ   mov  di, axπ   mov  ax, $A000π   mov  es, axπ   mov  al, Colorπ   mov  es:[di], alπ   pop  diπ   pop  esπend;ππPROCEDURE PlotPixel2(X, Y : word; Color : byte);πbeginπ if (X<320) then if (Y<200) then mem[$A000: Y*320+X] := color;πend;πππPROCEDURE SetColor (ColorNo, Red, Green, Blue : byte);πbeginπ     PORT[$3C8] := ColorNo;π     PORT[$3C9] := Red;π     PORT[$3C9] := Green;π     PORT[$3C9] := Blue;πend;πππvarπ LoopX : word;π LoopY, R, G, B, i : byte;π Ky : char;ππBeginπ Randomize;π InitVGA;π for LoopY := 0 to 199 doπ beginπ  for LoopX := 0 to 319 doπ   PlotPixel1(LoopX, LoopY, random(255)+1);π end;π B := 0;π repeatπ  G := random(63);π  for R := 0 to 63 doπ  beginπ   Setcolor(random(255)+1, R, G, B);π   inc(G, 1);π   if G=64 then G := 0;π  end;π  for G := 63 downto 0 doπ  R := random(63);π  beginπ   Setcolor(random(255)+1, R, G, B);π   dec(R, 1);π   if R=0 then R := 63;π  end;π  inc(B, random(10)-5);π  if B>63 then B := random(63);π until keypressed;π Ky := readkey;π InitTEXT;πend.πππ                            30     08-24-9417:54ALL                      RICH VERAA               Save/Restore Graphics    SWAG9408    =Σ3    11     ╓   ππProcedure GetImage (X1,Y1,X2,Y2:Integer;P:Pointer); assembler;πasmπ    mov  bx,320π    push dsπ    les  di,Pππ    mov  ax,0A000hπ    mov  ds,axπ    mov  ax,Y1π    mov  dx,320π    mul  dxπ    add  ax,X1π    mov  si,axππ    mov  ax,X2π    sub  ax,X1π    inc  axπ    mov  dx,axπ    stoswππ    mov  ax,Y2π    sub  ax,Y1π    inc  axπ    stoswπ    mov  cx,axππ  @@1:π    mov  cx,dxππ    shr  cx,1π    cldπ    rep  movswππ    test dx,1π    jz         @@2π    movsbπ  @@2:π    add  si,bxπ    sub  si,dxππ    dec  axπ    jnz  @@1ππ    pop  dsπend;ππProcedure PutImage (X1,Y1:Integer;P:Pointer); assembler;πasmπ    mov  bx,320π    push dsπ    lds  si,Pππ    mov  ax,0A000hπ    mov  es,axπ    mov  ax,Y1π    mov  dx,320π    mul  dxπ    add  ax,X1π    mov  di,axππ    lodswπ    mov  dx,axππ    lodswππ  @@1:π    mov  cx,dxππ    shr  cx,1π    cldπ    rep  movswππ    test dx,1π    jz         @@2π    movsbπ  @@2:π    add  di,bxπ    sub  di,dxππ    dec  axπ    jnz  @@1ππ    pop  dsπend;ππProcedure Init;πbeginπ  GetMem (Buf1,64000);π  GetMem(Buf2,64000);πend;ππbeginπ  init;π  dographicstuff;ππ  GetImage( 0,0,319,199,Buf1);  {store page 1}ππ  domoregraphicstuff;ππ  GetImage( 0,0,319,199,Buf2);  {store page 2}ππ  PutImage (0,0, Buf1);  {restore page 1}ππend.π                              31     08-24-9417:55ALL                      LUIS MEZQUITA            X3dunit                  SWAG9408    w¼è    78     ╓   unit x3dunit2;ππ{ mode-x 3D unit - xhlin-procedure by Sean Palmer }π{ Optimized by Luis Mezquita Raya                 }ππ{$g+}ππinterfaceππconst vidseg:word=$a000;π      divd:word=128;π      dist:word=200;π      minx:word=0;π      maxx:word=319;π      border:boolean=false;ππvar   ctab:array[byte] of integer;π      stab:array[byte] of integer;π      address:word;π      triangles:boolean;ππProcedure setborder(col:byte);πProcedure setpal(c,r,g,b:byte);πProcedure retrace;πProcedure setmodex;πProcedure setaddress(ad:word);πProcedure cls;πProcedure polygon(x1,y1,x2,y2,x3,y3,x4,y4:integer; c:byte);πFunction  cosinus(i:byte):integer;πFunction  sinus(i:byte):integer;ππimplementationππvar   xpos:array[0..199,0..1] of integer;ππProcedure setborder(col:byte); assembler;πasmπ        xor ch,chπ        mov cl,borderπ        jcxz @outπ        mov dx,3dahπ        in al,dxπ        mov dx,3c0hπ        mov al,11h+32π        out dx,alπ        mov al,colπ        out dx,alπ@out:πend;ππProcedure setpal(c,r,g,b:byte); assembler;πasmπ        mov dx,3c8hπ        mov al,[c]π        out dx,alπ        inc dxπ        mov al,[r]π        out dx,alπ        mov al,[g]π        out dx,alπ        mov al,[b]π        out dx,alπend;ππProcedure retrace; assembler;πasmπ        mov dx,3dah;π@vert1: in al,dxπ        test al,8π        jz @vert1π@vert2: in al,dxπ        test al,8π        jnz @vert2πend;ππProcedure setmodex; assembler;πasmπ        mov ax,13hπ        int 10hπ        mov dx,3c4hπ        mov ax,0604hπ        out dx,axπ        mov ax,0f02hπ        out dx,axπ        mov cx,320*200π        mov es,vidsegπ        xor ax,axπ        mov di,axπ        rep stoswπ        mov dx,3d4hπ        mov ax,0014hπ        out dx,axπ        mov ax,0e317hπ        out dx,axπend;ππProcedure setaddress(ad:word); assembler;πasmπ        mov dx,3d4hπ        mov al,0chπ        mov ah,[byte(ad)+1]π        out dx,axπ        mov al,0dhπ        mov ah,[byte(ad)]π        out dx,axπend;ππProcedure cls; assembler;πasmπ        mov es,vidsegπ        mov di,addressπ        mov cx,8000π        mov dx,3c4hπ        mov ax,0f02hπ        out dx,axπ        xor ax,axπ        rep stoswπend;ππ{$f-}ππProcedure polygon(x1,y1,x2,y2,x3,y3,x4,y4:integer; c:byte); assembler;πvar mny,mxy,y,m,mult,divi,top,s,π    stb,px1,py1,px2,py2:integer;π    dir:byte;πasm                                     { Procedure Polygon }π        mov ax,y1                       { Determine lowest & highest points }π        mov cx,axπ        mov bx,y2ππ        cmp ax,bx                       { if mny>y2 ==> mny:=y2 }π        jl @p2π        mov ax,bxππ@p2:    cmp cx,bx                       { if mxy<y2 ==> mxy:=y2 }π        jg @p3π        mov cx,bxππ@p3:    mov bx,y3π        cmp ax,bx                       { if mny>y3 ==> mny:=y3 }π        jl @p3Mπ        mov ax,bxππ@p3M:   cmp cx,bx                       { if mxy<y3 ==> mxy:=y3 }π        jg @p4π        mov cx,bxππ@p4:    mov bx,y4π        cmp ax,bx                       { if mny>y4 ==> mny:=y4 }π        jl @p4Mπ        mov ax,bxππ@p4M:   cmp cx,bx                       { if mxy<y4 ==> mxy:=y4 }π        jg @vertπ        mov cx,bxππ@vert:  cmp ax,0                        { Vertical range checking }π        jge @minin                      { if mny<0 ==> mny:=0 }π        xor ax,axπ@minin: cmp cx,200                      { if mxy>199 ==> mxy:=199 }π        jl @maxinπ        mov cx,199π@maxin: cmp cx,0                        { if mxy<0 ==> Exit }π        jl @pexitπ        cmp ax,199                      { if mny>199 ==> Exit }π        jg @pexitππ        mov mny,ax                      { ax=mny=lowest point }π        mov mxy,cx                      { cx=mxy=highest point }ππ        push x1                         { RangeChk(x1,y1,x2,y2) }π        push y1π        push x2π        push y2π        call @Rangeππ        push x2                         { RangeChk(x2,y2,x3,y3) }π        push y2π        push x3π        push y3π        call @Rangeππ        push x3                         { RangeChk(x3,y3,x4,y4) }π        push y3π        cmp Triangles,0π        jz @Poly4π        push x1π        push y1π        jmp @Lastππ@Poly4: push x4π        push y4π        call @Rangeππ        push x4                         { RangeChk(x4,y4,x1,y1) }π        push y4π        push x1π        push y1π@Last:  call @Rangeππ        mov ax,mny                      { Show a poly }π        mov di,ax                       { y:=mny }π        shl di,2π        lea bx,xposπ        add di,bx                       { di points to xpos[y,0] }π@Show:  mov y,ax                        { repeat ... }π        mov cx,[di]π        mov dx,[di+2]π        mov px1,cxπ        mov px2,dxπ        push axπ        push diπ        call @xhlin                     { xhlin(px1,px2,y,c) }π        pop diπ        pop axπ        add di,4                        { Next xpos }π        inc ax                          { inc(y) }π        cmp ax,mxy                      { ... until y>mxy; }π        jle @Showπ        jmp @pexitππ{ RangeChk }ππ@Range: pop di                          { Get return IP }π        pop py2                         { Get params }π        pop px2π        pop py1π        pop px1π        push di                         { Save return IP }ππ        mov ax,py1                      { dir:=byte(y1<y2) }π        cmp ax,py2π        mov ax,1π        jl @Rdwnπ        dec alπ@Rdwn:  mov dir,alππ        shl al,1π        push axπ        shl al,2π        sub ax,4π        mov stb,ax                      { stb:=8*dir-4 }π        pop axπ        dec ax                          { s:=2*dir-1 }π        mov s,ax                        { Check directions (-1= down, 1=up) }ππ        test AH,10000000b               { Calculate constants }π        mov dx,0π        jz @Rposiπ        dec dxπ@Rposi: mov bx,px2π        sub bx,px1π        imul bxπ        mov mult,ax                     { mult:=s*(x2-x1) }π        mov ax,py2π        mov bx,py1π        mov cx,axπ        sub ax,bxπ        mov divi,ax                     { divi:=y2-y1 }ππ        cmp bx,cx                       { ¿y1=y2? }ππ        pushf                           { Calculate pointer to xpos[y,dir] }π        mov y,bx                        { y:=y1 }π        mov di,bxπ        shl di,2π        lea bx,xposπ        add di,bxπ        mov cl,dirπ        mov ch,0π        shl cl,1π        add di,cx                       { di points to xpos[y,dir] }π        popfππ        je @Requ                        { if y1=y2 ==> @Requ }ππ        mov m,0                         { m:=0 }π        mov ax,py2π        add ax,sπ        mov top,ax                      { top:=y2+s }ππ@RLoop: mov ax,y                        { repeat ... }π        cmp ax,mny                      { if y<mny ==> @RNext }π        jl @RNextπ        cmp ax,mxy                      { if y>mxy ==> @RNext }π        jg @RNextππ        mov ax,m                        { Calculate int(m/divi)+x1 }π        test AH,10000000bπ        mov dx,0π        jz @RLposπ        dec dxπ@RLpos: mov bx,diviπ        idiv bxπ        add ax,px1π        call @HR                        { HorRangeChk(m div divi+x1) }ππ@RNext: mov ax,multπ        add m,ax                        { inc(m,mult) }π        add di,stb                      { Next xpos }π        mov ax,y                        { inc(y,s) }π        add ax,sπ        mov y,axπ        cmp ax,topπ        jne @RLoop                      { ... until y=top }π        jmp @Rexitππ@Requ:  mov ax,yπ        cmp ax,mny                      { if y<mny ==> Exit }π        jl @Rexitπ        cmp ax,mxy                      { if y>mxy ==> Exit }π        jg @Rexitπ        mov ax,px1π        call @HR                        { HorRangeChk(px1) }π@Rexit: jmp @exitππ{ HorRangeChk }ππ@HR:    mov bx,minx                     { bx:=minx }π        cmp ax,bxπ        jl @HRsavπ        mov bx,maxx                     { bx:=maxx }π        cmp ax,bxπ        jg @HRsavπ        mov bx,axπ@HRsav: mov [di],bx                     { xpos[y,dir]:=bx }π        jmp @exitπ{ xhlin }ππ@xhlin: mov es,vidsegπ        cldπ        mov ax,80π        mul yπ        mov di,ax                       { base of scan line }π        add di,addressππ        mov bx,px1                      { px1 = x begin coord }π        mov dx,px2                      { px2 = x end coord }π        cmp bx,dxπ        jb @skipπ        xchg bx,dx                      { switch coords if px1>px2 }ππ@skip:  mov cl,blπ        shr bx,2π        mov ch,dlπ        shr dx,2π        and cx,$0303π        sub dx,bx                       { width in Bytes }π        add di,bx                       { offset into video buffer }π        mov ax,$ff02π        shl ah,clπ        and ah,1111b                    { left edge mask }π        mov cl,chπ        mov bh,$f1π        rol bh,clπ        and bh,1111b                    { right edge mask }π        mov cx,dxπ        or cx,cxπ        jnz @leftπ        and ah,bh                       { combine left & right bitmasks }ππ@left:  mov dx,$03c4π        out dx,axπ        inc dxπ        mov al,cπ        stosbπ        jcxz @exitπ        dec cxπ        jcxz @rightπ        mov al,1111bπ        out dx,al                       { skipped if cx=0,1 }π        mov al,cπ        repz stosb                      { fill middle Bytes }ππ@right: mov al,bhπ        out dx,al                       { skipped if cx=0 }π        mov al,cπ        stosbππ@exit:  pop axπ        push csπ        push axπ        retπ@pexit:πend;ππ{$f+}ππFunction cosinus(i:byte):integer;πbeginπ cosinus:=ctab[i];πend;ππFunction sinus(i:byte):integer;πbeginπ sinus:=stab[i];πend;ππProcedure Initialize;πvar i:byte;πbeginπ triangles:=False;π for i:=0 to 255 do ctab[i]:=round(-cos(i*pi/128)*divd);π for i:=0 to 255 do stab[i]:=round(sin(i*pi/128)*divd);πend;ππbeginπ Initialize;πend.π                                                                                                                      32     08-24-9417:56ALL                      ANDREW GOLOVIN           X-mode Write Mode ExampleSWAG9408    äΦ¼ù    31     ╓   π{ Illustration on how VGA Write Mode 1 works }π{ by Andrew Golovin (2:5080/10@Fidonet)      }π{ Can be used at your own risk freely w/o    }π{ any charge                                 }π{============================================}π{ PREFACE:                                   }π{ This example illustrate posibility to save }π{ Bitmaps in unused VRam. And use VWM1 to    }π{ restore it by 4 pixels at one byte         }π{ Use arrows to move "bitmap" on screen.     }π{ This example _only_ illustrate this mode   }π{ Extremly needs optimization! Don't use it  }π{ as is. Just an idea.                       }ππUses CRT;πvarπ  OldMode: Byte;ππprocedure SetWriteMode(Wmode: Byte); assembler;πasmπ  Mov     DX,3cehπ  Mov     AL,5π  Out     DX,ALπ  Inc     DXπ  In      AL,DXπ  And     AL,11111100bπ  Or      AL,WModeπ  Out     DX,ALπend;ππprocedure Init320x200_X; assembler;πasmπ  Mov AH,0fh; Int 10h; Mov [OldMode],al; Mov AX,13h; Int 10h;π  Mov DX,3c4h; Mov AL,04h; Out DX,AL; Inc DX; In AL,DX; And AL,011110111b;π  Or AL,000000100b; Out DX,AL; Dec DX; Mov AX,0f02h; Out DX,AX;π  Mov AX,0a000h; Mov ES,AX; XOr DI,DI; Mov AX,0202h; Mov CX,8000h;π  ClD; RepNZ StoSW; Mov DX,3d4h; Mov AL,14h; Out DX,AL; Inc DX;π  In AL,DX; And AL,010111111b; Out DX,AL; Dec DX; Mov AL,017h;π  Out DX,AL; Inc DX; In AL,DX; Or AL,01000000b; Out DX,AL; Mov DX,3d4h;π  Mov AX,80; ShR AX,1; Mov AH,AL; Mov AL,13h; Out DX,AX; Retπend;ππProcedure PutPixel(x,y: Word; c: Byte);π  beginπ    asmπ      Mov    DX,3c4hπ      Mov    AL,02π      Out    DX,ALπ      Mov    AX,Yπ      ShL    AX,4π      Mov    DI,AXπ      ShL    AX,2π      Add    DI,AXπ      Mov    AX,Xπ      ShR    AX,2π      Add    DI,AXπ      Mov    AX,Xπ      And    AX,3π      Mov    CL,ALπ      Mov    AL,1π      ShL    AL,CLπ      Inc    DXπ      Out    DX,ALπ      Mov    AX,0a000hπ      Mov    ES,AXπ      Mov    AL,Cπ      StoSBπ    end;π  end;ππprocedure MaskBits(BitsToMask: Byte); assembler;π  asmπ    Mov     DX,3cehπ    Mov     AL,8π    Mov     AH,BitsToMaskπ    Out     DX,AXπ  end;ππProcedure MaskPlanes(PlaneToMask: Byte); assembler;πasmπ  Mov     DX,3c4hπ  Mov     AL,2π  Out     DX,ALπ  Inc     DXπ  Mov     AL,PlaneToMaskπ  Out     DX,ALπEnd;ππProcedure StoreBack(x,y,w,h: word; toAddr: word);π  varπ    curx,cury: Word;π  beginπ    SetWriteMode(1);π    MaskPlanes($f);π    MaskBits($ff);π    For CurY:=Y to Y+H doπ      Move(Mem[$a000:CurY*80+x],Mem[$a000:toAddr+(CurY-Y)*W],w);π    SetWriteMode(0);π  end;ππProcedure RestoreBack(x,y,w,h: word; fromAddr: Word);π  varπ    cury,curx: Word;π  beginπ    SetWriteMode(1);π    MaskPlanes($f);π    MaskBits($ff);π    For CurY:=Y to Y+H doπ      Move(Mem[$a000:fromAddr+(CurY-Y)*W],Mem[$a000:CurY*80+x],w);π    SetWriteMode(0);π  end;ππvarπ  x,y: Word;π  curx,cury: Word;π  c: Char;πBeginπ  Init320x200_x;π  For x:=0 to 319 doπ    For y:=0 to 199 doπ      PutPixel(x,y,(x +y) mod 16+16);π  StoreBack(0,0,3,12,16000);π  For x:=0 to 11 doπ    For y:=0 to 11 doπ      PutPixel(x,y,Random(255));π  StoreBack(0,0,3,12,16200);π  CurX:=0;CurY:=0;π  Repeatπ    Repeat Until KeyPressed;π    c:=ReadKey;π    If c=#0π       thenπ         beginπ           RestoreBack(CurX,CurY,3,12,16000);π           c:=ReadKey;π           Case c ofπ             #80: If CurY<187π                     thenπ                       Inc(CurY);π             #72: If CurY>0π                     Thenπ                       Dec(CurY);π             #75: If CurX>0π                     Thenπ                       Dec(CurX);π             #77: If CurX<77π                     Thenπ                       Inc(CurX);π           end;π           StoreBack(CurX,CurY,3,12,16000);π           RestoreBack(CurX,CurY,3,12,16200);π         end;π  Until c=#27;π  asm Mov al,OldMode; XOr AH,AH; Int 10h end;πEnd.ππ                                                                           33     08-25-9409:07ALL                      KIMMO K K FREDRIKSSON    Fastest Putpixel?        SWAG9408    Ö║3    22     ╓   (*πFrom: kfredrik@cc.Helsinki.FI (Kimmo K K Fredriksson)ππ:  > This routine, from off the net somewhere, is a little fasterπ:  > than simply writing to MEM (it replaces the multiply by aπ:  > shift).π: Wilbert van Leijen and I once wrote a similar thing like this as an InLineπ: macro, which turned out to be the true fastest code (ok, never say...)ππ: Procedure PutPixel18(c: Byte; x,y: Integer);π: Inline(π:   $B8/$00/$A0/      {  mov   AX,$A000   }π:   $8E/$C0/          {  mov   ES,AX      }π:   $5B/              {  pop   BX         }π:   $88/$DC/          {  mov   AH,BL      }π:   $5F/              {  pop   DI         }π:   $01/$C7/          {  add   DI,AX      }π:  {$IFOPT G+}π:   $C1/$E8/$02/      {  shr   AX,2       }π:  {$ELSE}π:   $D1/$E8/          {  shr   AX,1       }π:   $D1/$E8/          {  shr   AX,1       }π:  {$ENDIF}π:   $01/$C7/          {  add   DI,AX      }π:   $58/              {  pop   AX         }π:   $AA);             {  stosb            }ππ: I'd be real interested in seeing a PutPixel (remember: one pixel only, not aπ: line, that's another story) that is faster than this one...ππThis is fast indeed, but the last instruction should be replaced atπleast in 486 and Pentium CPUs with instruction mov es:[di],al, whichπis faster than stosb (and you may also want to re-arrange them).ππAlso, the shift and add sequence could be replaced by table look-up,πbut that wouldn't be so elegant, only faster. So if you wanna stickπwith arithmetic address calculation, you could use 32-bit instructions,πsomething like this:ππ mov es,[SegA000]π pop diπ pop bxπ pop axπ shl di,6π lea edi,[edi*4+edi]π mov es:[edi+ebx],alπ πIf I use 32-bit instructions, I usually zero data registers in theπinitialization part of my program, so I can use those registersπin the situations like above without the need to every time zeroπthe high bits.ππYou may also use fs or gs register instead of es, because you mayπalways keep it pointing to video RAM, instead of loading it everyπtime you do PutPixel.ππThis may go beyond the topic, but what the heck: usually I try toπuse the offset of the screen mem as the parameter of these kind ofπprocedures, because it removes the need of address calculation:π*)πPROCEDURE PutPixel( offset : Word; c : Byte );π  INLINE(π pop axπ pop diπ mov fs,[di],alπ);π(*πIt is still very easy to use the offset instead of the (x,y)πposition, if you want the next x-pix, add one to offset, ifπyou want the next y-pix, add 320 to offset.ππSorry, but I was too lazy to calc the hex values :-(ππAnd never say that you have the absolutely fastest code ;-)π*)π                                                                                                34     08-25-9409:08ALL                      YUAN LIU                 Virtual world plotting   SWAG9408    -G    38     ╓   {πFrom: yliu@morgan.ucs.mun.ca (Yuan Liu)ππ: I have a question for drawing a graphic.  I have a set of data.π: I want to read these data and plot them in the XY axes.  Does anyoneπ: know how to caculate the data to fit the X axis.  I am using TP 7.0.ππWhen converting from HP Pascal, which provides a nice subset of theπdevice-independent graphics kernal and allows plotting in the virtual worldπ(so the window and viewport can be set in the virtual world), I wroteπseveral procedures to simulate virtual world plotting.  The following isπpart of a unit Plotbase I created.ππThe function you needed is set_window; the boolean pagefit controlsπwhether you just want your plot to fit in the whole window or there's a concernπabout the isotropy of the plot.  I didn't bother to write a virtualπworld set_viewport as I can live without it.ππ}πUNIT PLOTBASE; {******************* Stored in 'PLOTBASE' ******************}π{*     Basic procedures for graphical manipulations.                      *}π{*     Created in 1983.  Updated 17/05/94 10:00 a.m.       By LIU Yuan    *}π{**************************************************************************}πinterface USES Graph;πprocedure set_window(left, right, up, down: extended; pagefit: boolean);π         {Sets a mapping of virtual window on the current viewport;π           use isotropic scaling if not pagefit.}πfunction vToX(x: extended): integer;πfunction vToY(y: extended): integer;π         {Map x, y in the virtual world onto real world}πfunction XtoV(X: integer): extended;πfunction YtoV(Y: integer): extended;π         {Maps X, Y in the real world onto virtual world}π           use isotropic scaling if not pagefit.πprocedure vMove(x, y: extended);π          {Moves the current position to (x,y) in the virtual world}πprocedure vMoveRel(Dx, Dy: extended);π{Moves the current position a relative distance in the virtual world}πprocedure vLine(x1, y1, x2, y2: extended);π          {Draws a line from (x1,y1) to (x2,y2) in the virtual world}πprocedure vLineTo(x, y: extended);π          {Draws a line from current position to (x,y) in the virtual world}πfunction str_width(str: string): extended; {string width in the virtual world}πfunction str_height(str: string): extended; {string height in the virtualπworld}πimplementation {************************** PLOTBASE *************************}π        var Text:         string[20];π            xasp, yasp, xbase, ybase: extended;π            {convert from virtual world to display}ππprocedure set_window(left, right, up, down: extended; pagefit: boolean);π         {Sets a mapping of virtual window on the current viewport;π           use isotropic scaling if not pagefit.π           Side effects: xasp, yasp, xbase, ybase.}πvar view: ViewPortType;πbegin xbase:=left; ybase:=down; right:=right-left; up:=up-down;π      GetViewSettings(view);π      right:=(view.x2-view.x1)/right;π      up:=(view.y2-view.y1)/up;π      if pagefit then begin xasp:=right; yasp:=up endπ      else if right<up then begin yasp:=right; xasp:=right; endπ                       else begin xasp:=up; yasp:=up endπend; {set_window}ππfunction vToX(x: extended): integer;begin vToX:=round((x-xbase)*xasp) end;π         {Maps x in the virtual world onto real world}πfunction vToY(y: extended): integer;begin vToY:=round((y-ybase)*yasp) end;π         {Maps x in the virtual world onto real world}ππfunction XtoV(X: integer): extended; begin XtoV:=X/xasp+xbase end; {XtoV}π         {Maps X in the real world onto virtual world}πfunction YtoV(Y: integer): extended; begin YtoV:=Y/yasp+ybase end; {YtoV}π         {Maps Y in the real world onto virtual world}ππprocedure vMove(x, y: extended);π          {Moves the current position to (x,y) in the virtual world}πbegin MoveTo(round((x-xbase)*xasp),round((y-ybase)*yasp)) end; {vMove}πprocedure vMoveRel(Dx, Dy: extended);π{Moves the current position a relative distance in the virtual world}πbegin MoveRel(round(Dx*xasp),round(Dy*yasp)) end; {vMoveRel}ππprocedure vLine(x1, y1, x2, y2: extended);π          {Draws a line from (x1,y1) to (x2,y2) in the virtual world}πbegin line(round((x1-xbase)*xasp),round((y1-ybase)*yasp),π           round((x2-xbase)*xasp),round((y2-ybase)*yasp)) end; {vLine}ππprocedure vLineTo(x, y: extended);π          {Draws a line from current position to (x,y) in the virtual world}πbegin LineTo(round((x-xbase)*xasp),round((y-ybase)*yasp)) end; {vLineTo}ππfunction str_width(str: string): extended; {string width in the virtual world}πbegin str_width:=TextWidth(str)/xasp end; {str_width}ππfunction str_height(str: string): extended; {string height in the virtualπworld}πbegin str_height:=TextHeight(str)/yasp end; {str_height}π                                                                35     08-25-9409:11ALL                      MIKE CHURCH              Stars AGAIN!!!!          SWAG9408    ëcè╛    31     ╓   {πOk...  Here goes.  You will have to figure out how to TSR this if youπwant...  But you can navigate in this one too!  TP v6.0π}ππprogram stars;π{$R-}π{$S-}    {dangerous, but it's pretty well debugged}π{$G+}πuses crt;πconst MaxStars=1000;         { OK for 486-33. Decrease for slower computers}π      xltsin:integer=0;π      xltcos:integer=round((1-(640/32767)*(640/32767))*32767);π      yltsin:integer=0;π      yltcos:integer=round((1-(640/32767)*(640/32767))*32767);π      zltsin:integer=0;π      zltcos:integer=round((1-(640/32767)*(640/32767))*32767);π                {rotation parameters, 16-bit.}π      speed:word=264;    {speed of movement thru starfield}πconst XWIDTH = 320;  { basic screen size stuff used for star animation.}πconst YWIDTH = 200;πconst XCENTER = ( XWIDTH div 2 );πconst YCENTER = ( YWIDTH div 2 );πtype STARtype=recordπ                x,y,z:integer; {The x, y and z coordinates}π                xz,yz:integer; { screen coords}π              end;πvar star:array[1..maxstars] of startype;π    i:integer;π    ch:char;π    rotx,roty,rotz:boolean;π    rotxv,rotyv,rotzv:integer;πprocedure setmode13;    {sets 320*200 256-colour mode}πassembler;πasmπ  mov ax,13hπ  int 10hπend;πprocedure settextmode;   {returns to text mode}πassembler;πasmπ  mov ax,03hπ  int 10hπend;πprocedure setpix(x,y:integer;c:byte);  {NO BOUNDARY CHECKING!}πbegin   {Sets a pixel in mode 13h}πasmπ  mov ax,0a000hπ  mov es,axπ  mov ax,yπ  mov bx,320π  mul bxπ  mov di,xπ  add di,axπ  mov al,cπ  mov es:[di],alπend;πend;πprocedure initstar(i:integer);  {initialise stars at random positions}πbeginπ  with star[i] doπ  beginπ    x := longint(-32767)+random(65535);π    y := longint(-32767)+random(65535);             {at rear}π    z := random(16000)+256;π    xz:=xcenter;π    yz:=ycenter;π  end;πend;πprocedure newstar(i:integer);   {create new star at either front or}πbegin                            {rear of starfield}π  with star[i] doπ  beginπ    x := longint(-32767)+random(65535);π    y := longint(-32767)+random(65535);π    if z<256 then z := random(1256)+14500     {kludgy, huh?}π      else z:=random(256)+256;π    xz:=xcenter;π    yz:=ycenter;π  end;πend;ππ{$L update.obj}πprocedure update(var star:startype;i:integer);external;πππππbeginπ   {gets ~100 frames/sec on a 486-33 with 500 stars,π       rotating on 1 axis, speed 256}π  clrscr;π  checkbreak:=false;                      { for speed?}π  randomize;π  for i:=1 to maxstars do initstar(i);    {initialise stars}π  setmode13;π  rotx:=true;roty:=true;rotz:=true;π  ch:=' ';π  repeatπ    for i:=1 to maxstars do update(star[i],i);  {update star positions}π    if keypressed thenπ    beginπ      ch:=readkey;                       { change parameters according to }π      if ch='+' then speed:=speed+32;    {  key pressed}π      if ch='-' then speed:=speed-32;π      if ch=#13 thenπ         beginπ              xltsin:=0;π              yltsin:=0;π              zltsin:=0;π              speed:=256;π         end;π      if ch=#80 then dec(xltsin,96);π      if ch=#72 then inc(xltsin,96);π      if ch=#77 then dec(yltsin,96);π      if ch=#75 then inc(yltsin,96);π      if ch=#81 thenπ         beginπ              dec(yltsin,96);π              if xltsin<0 then inc(zltsin,96);π              if xltsin>0 then dec(zltsin,96);π         end;π      if ch=#79 thenπ         beginπ              inc(yltsin,96);π              if xltsin<0 then dec(zltsin,96);π              if xltsin>0 then inc(zltsin,96);π         end;π      if ch=#71 then dec(zltsin,96);π      if ch=#73 then inc(zltsin,96);π      end;π    xltcos:=round((1-sqr(xltsin/32767))*32767);π    yltcos:=round((1-sqr(yltsin/32767))*32767);    { evaluate cos values}π    zltcos:=round((1-sqr(zltsin/32767))*32767);π  until ch=#27;       {hit ESC to exit}π  settextmode;π  writeln;πend.π                                                36     08-25-9409:11ALL                      BOB SCHOR                Storing 3D Graphics      SWAG9408    ╖Me∞    27     ╓   {πFrom: Bschor@vms.cis.pitt.eduππ> Now the problem. "Seek(F, I)" will only take ONE integer at a time!!π> Naturally I need two. I'm trying to run it so that at each virtualπ> "square" a user can define a different message, monster, etc. And theπ> file i'm writing to must be able to define between X & Y, [(1,2) forπ> example], or both of them togeter [E.G. Two steps to the right, two stepsπ> forward = (2,2)]. HOW DO I DO THIS???ππIf I understand the question correctly, you are asking how to map aπtwo-dimensional structure (a 2-D map of your world) into a 1-dimensionalπdata structure (a file).  Ah, my ancient Fortran knowledge does come inπuseful ...ππThe following works for arrays of any dimension, though you need toπhave the array size fixed.  Suppose you have dimensioned World into R rows,πC columns, and L layers (I'm doing 3-D, just to show how it can be done).πTo make it all very clear, I'll define the world as either a 3-D or linearπstructure, using the Pascal Variant Record type.π}ππCONSTπ rows = 30;π columns = 40;π layers = 5;π rooms = 6000; { rows * columns * layers }πTYPEπ rowtype = 1 .. rows;π columntype = 1 .. columns;π layertype = 1 .. layers;π roomnumbertype = 1 .. rooms;π roomtype = RECORDπ { you define as needed }π END;π worldtype = RECORDπ CASE (d3, d1) ofπ d3 : (spatial: ARRAY [layertype, rowtype, columntype] OF roomtype);π d1 : (linear : ARRAY [roomnumbertype] OF roomtype);π END;π{π     Basically, you determine an order you wish to store the data.  Supposeπyou say "Start with the first layer, the first row, the first column.πMarch across the columns, then move down a row and repeat across theπcolumns; when you finish a layer, move down to the next layer and repeat".ππ     Clearly Layer 1, Row 1, Column C maps to Room C.  Since each row hasπ"columns" columns, then the mapping of Layer 1, Row R, Column C is toπRoom (R-1)*columns + C.  The full mapping is --π}π  FUNCTION roomnumber (layer : layertype; row : rowtype;π   column : columntype) : roomnumbertype;ππ  BEGIN   { roomnumber }π   roomnumber := column + pred(row)*columns + pred(layer)*columns*rowsπ  END;ππ{     Note you can also map in the other direction:}ππ  FUNCTION layer (roomnumber : roomnumbertype) : layertype;ππ  BEGIN   { layer }π   layer := succ (pred(roomnumber) DIV (columns * rows))π  END;ππ  FUNCTION row (roomnumber : roomnumbertype) : rowtype;ππ  BEGIN   { row }π   row := succ ((pred(roomnumber) MOD (columns * rows)) DIV columns)π  END;ππ  FUNCTION column (roomnumber : roomnumbertype) : columntype;ππ  BEGIN   { column }π   column := succ (pred(roomnumber) MOD columns)π  END;ππ{π     Putting it all together, suppose you have a room, "room", with roomπnumber "roomnumber", that you want to put into the world.π}π VAR world : worldtype;π     room : roomtype;π     roomnumber : roomnumbertype;ππ WITH world DOπ  BEGINπ   spatial[layer(roomnumber), row(roomnumber), column(roomnumber)] := roomπ  END;π{π     The above fragment stores a room into the three-dimensional world.πOf course, if you know the room number (which we do), you can also simplyπ}ππ WITH world DO linear[roomnumber] := roomπ{π     For the original question, note that the "roomnumber" function givesπyou the record number for the Seek procedure (you may need to offset by 1,πdepending on how Seek is implemented ...).π}π